How to find whether the user clicks browser back button or Refresh button

125

Solution 1

First of all, giving error messages if users use Back or have to refresh a page for whatever reason, is a really bad idea. Instead, you should transparently deal with that. Think about a page not coming up fully because of problems on the transportation level - the only option the user has is to reload or go back.

To answer your question, you have to keep track of the user's navigation yourself, that means on the server side. Forget about java-script here. If the user visits a website, you can store that information in a Session associated to the user (there are several methods of keeping these unique sessions, and I won't go into details here). If you store in your internal structures which pages the user visited lately, it is easy to determine a page being visited twice, or navigation going into the "wrong" direction.

You could easily generalize this (and making the whole thing more robust, for example against users jumping wildly between urls, or going back more than one step at once) by building a graph of "allowed" navigation and traversing it while the user is visiting websites.

The correct behaviour then if the user is doing a "wrong" navigation (like stepping back, reloading == visiting twice) is to get him back on track. Not to give an error message he can't escape! As he is not allowed to reload or go back, he has no options left.

Solution 2

Implement a PageToken using a guid/or timestamp stored in session and compare the value to a hidden field on the form. I did this via a PageToken Class. If the value from the hidden field and the session variable don't match then you're out of synch and you handle that. The trick is to map all events on your page.

public void GeneratePageToken()
{
    SessionVariables currSession = new SessionVariables();
    hfMasterPageToken.Value = System.DateTime.Now.ToString();
    currSession.PageToken = hfMasterPageToken.Value;
}

public string GetLastPageToken
{
    get
    {
        SessionVariables currSession = new SessionVariables();
        return currSession.PageToken;
    }
}

public bool TokensMatch
{
    get
    {
        SessionVariables currSession = new SessionVariables();
        return (currSession.PageToken != null
            && currSession.PageToken == hfMasterPageToken.Value);
    }
}

In your Event method before your regular code:

if (this.TokensMatch == false)
{
    //Reload the data.
    //Generates a NewPageToken (this.GeneratePageToken();)
    ReloadDataMethod();
    this.MessageToUser =
     "Data reloaded.  Click Edit or Insert button to change.";
    this.MessageType = MessageToUserType.Success;
    this.DisplayMessageToUser = true;
    return;
}

Solution 3

You can't. The browser doesn't send it's own ui events to the server. All you get are http requests and one looks pretty much like another. Maybe the clicked the back button or maybe they just retyped the last url in. Tell us what problems it's causing and we can help you adapt your project to work with the http protocol a little better.

Solution 4

With Site.Master

In your Site.Master, put after <body>

<asp:ScriptManager ID="ScriptManager1" runat="server" EnablePageMethods="true" />
<dx:ASPxLoadingPanel ID="MainLoadingPanel" runat="server" ClientInstanceName="MainLoadingPanel" Modal="True" />
<input type="hidden" id="refreshed" value="no" />
<script type="text/javascript" language="javascript">
    MainLoadingPanel.Show();
    window.onload = function () {
        var e = document.getElementById("refreshed");
        if (e.value == "no") {
            MainLoadingPanel.Hide();
            e.value = "yes";
        } else {
            e.value = "no";
            location.reload(true); // Reload the page or redirect...
        }
    };
</script>

Without Site.Master

In your common code, put after <body>

<input type="hidden" id="refreshed" value="no" />
<script type="text/javascript" language="javascript">
    window.onload = function () {
        var e = document.getElementById("refreshed");
        if (e.value == "no") {
            e.value = "yes";
        } else {
            e.value = "no";
            location.reload(true); // Reload the page or redirect...
        }
    };
</script>

Solution 5

I presume you want to do this because of post-back to avoid resubmitting some action or data right? ironically, this wasn't as huge of a problem back before asp.net webforms ... because you generally had to post to a different URL instead of the same one (much like asp.net mvc actually).

One trick I liked to use ... even though in the most technical of points is slower ... was to have an input page, and a post page. The HTML output of the post page was some super minimal HTML with a tiny javascript that replaced the current url (of the post page) in the browser's history with the result page (or even the original referring page if you really wanted). The result was when the user would click the back button, he'd be sent to the original input page, or if he clicked refresh, he'd already be on the new result page.

<html><body onload="location.replace('someURL.asp')"></body></html>
Share:
125
Riffer
Author by

Riffer

Updated on July 13, 2020

Comments

  • Riffer
    Riffer almost 4 years

    I recently was saving data in a dictionary using XNA XML content

    <Asset Type="System.Collections.Generic.Dictionary[System.String, Microsoft.Xna.Framework.Vector2]">
    

    The dictionary works, but it doesn't allow me to save duplicate keys. So now I want to use a List of key value pairs. I tried the following:

    <Asset Type="System.Collections.Generic.List[KeyValuePair[System.String, Microsoft.Xna.Framework.Vector2]]">
    

    However, this doesn't work. Does Anybody know how to correctly do this?

  • ypnos
    ypnos over 14 years
    The one who gave -1 could state a reason, please!
  • GlennG
    GlennG almost 11 years
    There are some valid reasons for stopping a page refresh, generally at the completion of a transaction. However, as you say, you need to detect this on the server and display an appropriate page/message (e.g. your payment has already been taken).
  • Off The Gold
    Off The Gold about 10 years
    But what if you are not using Master Pages?
  • dcinadr
    dcinadr almost 10 years
    It's better to answer the question asked rather than state why you don't think it should be done in the first place.
  • ypnos
    ypnos almost 10 years
    I give the answer that I think is most helpful to the inquirer. The form might not completely align with the question because asking a question right is sometimes just as hard as giving a right answer. In this specific case, @balaweblog himself agreed that my answer was the most helpful to him amongst several others by accepting my answer. I honestly don't understand how you think you know any better six years later and feel the urge to give a down vote. Have a nice day though.
  • Casper Leon Nielsen
    Casper Leon Nielsen over 9 years
    interesting idea. However hard to translate to only a single page the shares a masterpage with other pages (that want to support refresh) - can you elaborate?