Is it possible to detect a page refresh (F5) serverside?
Asked Answered
M

5

6

...in comparison to requests of normal link click behaviour. I thought I might be able to use this to throw away some cached stuff on the serverside. For a more technical orientated target audience this could be a relative natural way of clearing a cache for i.e. graphs and charts.

To be clear - I am using ASP.NET MVC

Moretta answered 16/10, 2013 at 20:11 Comment(4)
Use normal cache expiration rules/policies. You can check the cache/etag headers sent from the client and react accordingly - but it might be easiest to say if this resource is fetched, then regenerate it and otherwise rely on the client correctly honoring the cache headers sent.Magdalenmagdalena
related: #8861637Luckey
Do you care about difference between a refresh and having the same page requested again?Clothesbasket
Maybe this helps: superuser.com/questions/17464/…Corny
C
5

I've just checked the three browsers you're likely to care about, and all three add extra cache headers in the request when you refresh the page. Conceivable you could check for those headers to throw out some server-side cache. It also seems a logical and natural way to do it.

  • IE: adds "Pragma: no-cache"
  • Chrome: adds "Cache-Control: max-age=0" and "If-Modified-Since: Tue, 17 Dec 2013 10:16:22 GMT" (disclaimer: time may vary)
  • Firefox: adds "Cache-Control: max-age=0"

I just checked this by refreshing this page in all three browsers, and checking Fiddler. It is possible there is more sophisticated logic going on that I haven't caught on to.

Cullie answered 17/12, 2013 at 10:29 Comment(1)
Tried in IE 11, it does not add "Pragma: no-cache" to Request.Headers (checked Request in Visual Studio)Stadiometer
B
2

Since it's in MVC, I would use the TempData to achieve this. On the first load of your method, you can set a value in the TempData so on the next load(the refresh) you would have a value set in this.

Let say you have a Add method, I think that should do the trick :

public virtual ActionResult Add(Model model)
        {
            if(TempData.ContainsKey("yourKey"))
            {
                //it means that you reload this method or you click on the link
                //be sure to use unique key by request since TempData is use for the next request 
            }

            TempData.Add("yourKey", true);

            return View(model);
        }
Barbiturism answered 11/12, 2013 at 20:37 Comment(0)
N
1

Add this script to your head section:

<script>
        $(window).keydown(function (e) {
            if (e.which == 116) {
                e.preventDefault();
                var l = window.location;
                var lp = (l + "?").split('?');
                window.location = lp[0] + "?f5=1&" + lp[1];
                return false;
            }
        });
    </script>

In server side just check if Request["f5"]=="1"

If you prefer not to modify the URL, you may add a temporary cookie. something like this:

<script>
        $(window).keydown(function (e) {
            if (e.which == 116) {
                AddCookie("F5","1")
            }
        });
</script>

On page load check if the cookie exists and delete it for next request.

Nurture answered 11/12, 2013 at 21:10 Comment(2)
you mentioned: "in comparison to requests of normal link click behaviour.". so clicking on address bar and pressing enter would be a normal link click.Nurture
So what? Author talked about F5. It meets the requirementKistna
C
0

You could compare the current session ID to the last page that was loaded and then compare the IsPostBack command.

If IsPostBack is true you know the user has clicked something on that page to post the page back. If the last page that was retrieved for the current session ID was not the same as the page you are currently loading then they arrived at this page from another page. If the last page that was retrieved is the same for the current session ID as the current page you are processing then this was likely a refresh (F5).

The only problem would be that you would detect F5 the same as someone putting their cursor in the address bar and hitting the Enter key once the page had finished loading, but I doubt this would be a problem for you.

EDIT: There seems to be some confusion on the comments about how this system would work so let me explain further. As was pointed out to me IsPostBack is not available in MVC so you have to test for post backs as shown here:

ASP.NET MVC - Is IsPostBack still here?

Let us consider the three ways in which you can end up at a page, any page. For our examples let us assume we want to detect refreshes on page X.

You can get to Page X these ways: 1. User presses a button on page A which takes you to page X. 2. User presses a button on Page B which posts you back to page B (post back). 3. User presses F5 or reloads the page some other way. - this is the one we want to detect..

There is scenario 4 which is 'user comes to page X from another site' but this would start a new session so let us not consider this.

Everytime a user loads a page you store that page somewhere along with the SessionID. The SessionID is constant for any one user for the duration of the session time out. There are some caveats to this such as accessing from different browsers on a single machine but I do not want to confuse matters.

Scenario 1: User loads page A, we look in our memory and there are no records at present. We store 'Page A' and the sessionID in memory. User clicks button on Page A. User is redirected, posts or transferred to Page B. Page B loads, we check the 'IsPostBack' flag, it may or may not be true at this point. If it is we know it is not a refresh, if it is false we need to continue to test as follows. we look in our memory and there is a record for 'Page A' for the current Session ID (remember the session ID does not change between requests for any given user). because the previous page was 'Page A' and we are on Page B we know this is NOT a refresh. We store 'Page B; and the sessionID in memory (in practice we either erase or update the previous record pointing to Page A).

Scenario 2: User loads page B, we store 'Page B' and the sessionID in memory. User clicks a button on page B. Page B loads, we check 'IsPostBack' flag. It is true so we know this is not a refresh.

Scenario 3: User loads Page B, we store 'Page B' and the sessionID in memory. User refreshes the page or reloads it by putting their cursor in the address bar and hitting enter. Page B loads, we check the 'IsPostBack' flag, it is false so we need to continue to test as follows. we look in our memory and there is a record for 'Page B' for the current Session ID. Because the previous page was 'Page B' and we are on Page B we know this IS a refresh.

By using this approach you can detect refreshes. If you are using MVC you can test Request.HttpMethod=="POST"

The only problem you get is if the user does a POST, you do a redirection, then the user goes back one page and refreshes from there are is will resubmit the form, sending the POST again. This will be detected as a fresh submission when it is actually a refresh. This can be eliminated using a Nonce approach or something similar.

Calix answered 11/12, 2013 at 16:38 Comment(7)
SessionId will not change except until user session is ended or you manage your session to change on every request.Nurture
Yes, that's the idea. You know the session ID will not change so you use that to know if two successive requests are from the same user.Calix
Craig, I think you misunderstand. Session ID will NOT help you distinguish between an initial request and refresh. The session ID will be the same. The answer and response are nonsensical. Also, IsPostBack doesn't exist in MVC. Only your last point was relevant; there is a difficulty in distinguishing between a refresh and another url request. That was the point.Clothesbasket
I did not know that isPostBack does not exist in MVC, it does work within WebForms though as I currently use this approach.Calix
I have expanded my response to explain further and to try to clear up the apparent confusion around using this method.Calix
Craig, you still haven't explained how sessionID could possibly change without session expiring. Or, what that has to do with a refresh.Clothesbasket
What makes you think the session ID is changing? I haven't said that at any point. You use the Session ID to identify the user so that you know who made any two successive requests. The session ID does not change, that's the whole point. If session ID 123456 opened page B on their last request, and session ID 123456 is opening page B on their current request then that single user has opened the same page twice in a row.Calix
G
0

A reliable, browser independent method works as follows: On every (non-ajax) request to the server, you pass a newly created random Guid as a (form or query string) parameter. Let's call it pageReloadIndicator. On server side, you remember pageReloadIndicator of every (non-ajax) request in the session. When a new request comes in, you compare the pageReloadIndicator from the last request with the one from the current request. When it is the same, you have a page reload. When it is different, you have a "regular" request.

Gaillard answered 11/10, 2023 at 8:56 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.