If you are reading this you are looking for an alternative to window.location.replace.
window.location.replace works perfectly until a user clicks the back button on their browser particularly IE .
Instead of being brought to the previous page the visitor is brought usually to an unexpected page,
usually the last page that was navigated to via non JavaScript means.
When I first encountered the problem, I resorted to the forums to find no real solution.
One solution was to use window.location.href instead of window.location.replace, this works in IE but not in Firefox.
The other common suggestion was to remove/amend the charset on each page.
<meta content="text/html; charset=utf-8" http-equiv="content-type" />
This would somehow trick IE into taking the correct action.
My advice is to simply give up trying to find a simple solution.
So what did we do?
The solution where we encountered the problem is an ASP.NET solution. We had a Repeater that had a collection bound to it.
| <asp:Repeater id="repArtists" runat="server" EnableViewState="false"> |
| <ItemTemplate> |
| <div class="node <%# Container.ItemIndex%2==0?"artist_odd":"artist_even" %>" onclick="ViewArtist("<%# ((Artist)Page.GetDataItem()).ArtistLinkUrl %>")"> |
| <%# SevenDigitalAdminButtons.AdminArtist((Artist)Page.GetDataItem(), "position:absolute; margin-left:-20px; margin-top:-10px;") %> |
| <div class="artist_image"> |
| <img src="<%# ((Artist)Page.GetDataItem()).ArtistImage %>" width="60px" /> |
| </div> |
| <h3><a href="<%# ((Artist)Page.GetDataItem()).ArtistLinkUrl %>" title="<%# ((Artist)Page.GetDataItem()).ArtistName%>"><%# TextManipulator.SubString(((Artist)Page.GetDataItem()).ArtistName, 15, "...") %></a></h3> |
| </div> |
| </itemtemplate> |
| </asp:Repeater> |
The rendered result was a matrix of Html DIVs, these divs when clicked brought the user to the desired page.
Linking the images and text in the node is fine but we wanted to link the whole thing without having to change the display attributes of the element.
So the first thing that came to mind is of course was window.location.replace.
Unable to use window.location.replace we came up with the following simple solution.
The Repeater above is located in a User Control, we simply implemented the IPostBackEventHandler interface, and linked our JavaScript with our event.
The complete source of our User Control code behind is as follows...
| using System; |
| using System.Collections.Generic; |
| using System.Linq; |
| using System.Web; |
| using System.Web.UI; |
| using System.Web.UI.WebControls; |
| using System.Text; |
| using SevenDigital; |
| using SevenDigital.Data; |
| using SevenDigital.Web; |
| using PixelPress.Interface; |
| using PixelPress.Interface.Data; |
| using PixelPress.Interface.Web; |
| |
| namespace Goldendiscs.Site.WEBCOMS._7Digital.Artist |
| { |
| public partial class Artist_Snapshot_Matrix : System.Web.UI.UserControl, IPostBackEventHandler |
| { |
| public ArtistGroup CurrentArtistGroup = new ArtistGroup(); |
| public ArtistList AllArtists = new ArtistList(); |
| |
| protected void Page_Load(object sender, EventArgs e) |
| { |
| RegisterScripts(); |
| CurrentArtistGroup = ArtistGroupSession.FromAttribute(this.Attributes); |
| |
| if (CurrentArtistGroup.Signed) |
| { |
| litTitle.Text = CurrentArtistGroup.ArtistGroupTitle; |
| litDescription.Text = CurrentArtistGroup.ArtistGroupDescription; |
| |
| AllArtists = ArtistGroupDAL.ArtistGroupArtists(CurrentArtistGroup); |
| repArtists.DataSource = AllArtists; |
| repArtists.DataBind(); |
| } |
| else |
| { |
| ComponentMapping currentMapping = ComponentMappingContext.FromAttribute(this.Attributes); |
| ComponentMappingDAL.DeleteMapping(currentMapping); |
| } |
| |
| } |
| |
| |
| |
| public void RegisterScripts() |
| { |
| StringBuilder script = new StringBuilder(); |
| |
| script.AppendLine("function ViewArtist(artistUrl)"); |
| script.AppendLine("{"); |
| script.AppendLine( Page.ClientScript.GetPostBackEventReference(this, "artistUrl").Replace("'", "")); |
| script.AppendLine("}"); |
| |
| string key = this.GetType().Namespace; |
| if (!Page.ClientScript.IsClientScriptBlockRegistered(key)) |
| { |
| Page.ClientScript.RegisterClientScriptBlock(this.GetType(), key, script.ToString(), true); |
| } |
| } |
| |
| public void RaisePostBackEvent(string eventArgument) |
| { |
| Response.Redirect(eventArgument); |
| } |
| } |
| } |
| |
| |
So when our release is clicked, it invokes our RaisePostBackEvent and we redirect the user to the desired page.
When the user clicks back, there are no problems.