Pages

Advertisement

Wednesday, July 11, 2007

Getting Rid of the Back Button Problem

A web browser's back button is essential for users to navigate across different web sites and web pages. However, for certain data sensitive web applications, using a web browser's back button can have unexpected and undesirable results. With poor planning, it could even crash a web site.

Take the following scenario as an example:

You developed a web survey for users to complete. Once the survey is submitted, the response is recorded in a database with a pre-coded caseID. Now, suppose a user just submitted his survey, then for some reason, he hit the browser's back button. Then, with or without making any changes, he submitted the survey again. Here, you ended up with two records (duplicate or not) with the same caseID. If the caseID is set to be unique, the user would get an error message.

In fact, the back button problem has pestered programmers for so long and caused so many headaches that across the net there is a flurry of questions, such as "How do I disable a browser's back button?".

Unfortunately, it is not possible to disable a browser's back button. Nor is it a good idea to do so. However, viable and simple solutions to get rid of this annoyance do exist.

The following is how you code it in a Class ASP way:

<%
Response.Buffer = True
Response.ExpiresAbsolute = Now() - 1
Response.Expires = 0
Response.CacheControl = "no-cache"
%>

This code snippet basically directs the page in concern to expire immediately once it is posted and set the page to cache none of its content. In ASP .NET, you can do something similar to disable browser page caching, like the following:

   Response.Cache.SetCacheability(HttpCacheability.NoCache);
Response.Cache.SetExpires(Now.AddSeconds(-1));
Response.Cache.SetNoStore();
Response.AppendHeader("Pragma", "no-cache");

You can place the code in the page_load event. Ideally, the code should be executed whenever the page is loaded. And, whenever a user tries to go back to the page, he/she should get a "Page has Expired" warning.

However, some browsers may ignore the page cache settings and some users may still get away with submitting a form multiple times. This leads us to a second, more reliable solution: the timestamp solution. You should always use this solution while also adding the response caching instructions to the Page_Load procedure.

Here is the code showing you how:

   protected void Page_Load(object sender, EventArgs e)
{
Response.Cache.SetCacheability(HttpCacheability.NoCache);
Response.Cache.SetExpires(Now.AddSeconds(-1));
Response.Cache.SetNoStore();
Response.AppendHeader("Pragma", "no-cache");

if (Page.IsPostBack){
if (isPageExpired()){
Response.Redirect("expired.htm");
}
else {
Session("TimeStamp") = Now.ToString;
ViewState("TimeStamp") = Now.ToString;
}
}
//...........
//your own function here
}

private boolean isPageExpired()
{
if (Session("TimeStamp") == null ||
ViewState("TimeStamp") == null)
return false;
else if (Session("TimeStamp") == ViewState("TimeStamp"))
return true;
else
return false;
}

The code is pretty self-explanatory. Whenever a page is loaded, it checks whether it is a resubmitted one by calling the isPageExpired function. If the function returns true, it redirects the page to the page-expired response; if not, it sets two timestamps: one saved in session state, the other view state.

The isPageExpired function compares the timestamp saved in session state and the timestamp in viewstate. If they are different, the user has submitted a form from cache; then, the page directs them to the Page-expired response.

No comments: