是否可以检测页面刷新(F5)服务器端?

时间:2013-10-16 20:11:18

标签: asp.net asp.net-mvc web server-side

...与普通链接点击行为的请求相比较。我以为我可以用它来丢弃服务器端的一些缓存内容。对于面向技术的目标受众而言,这可能是清除图表和图表缓存的一种相对自然的方式。

要明确 - 我正在使用ASP.NET MVC

4 个答案:

答案 0 :(得分:4)

我刚刚检查了您可能关心的三个浏览器,并且当您刷新页面时,这三个浏览器都会在请求中添加额外的缓存标头。可以想象,您可以检查这些标头是否会丢弃一些服务器端缓存。这似乎是一种合乎逻辑且自然的方式。

  • IE:添加“Pragma:no-cache”
  • Chrome:添加“Cache-Control:max-age = 0”和“If-Modified-Since:Tue,2013年12月17日10:16:22 GMT”(免责声明:时间可能会有所不同)
  • Firefox:添加“Cache-Control:max-age = 0”

我刚刚通过在所有三个浏览器中刷新此页面并检查Fiddler来检查这一点。有可能存在更复杂的逻辑,我没有抓住它。

答案 1 :(得分:2)

因为它在MVC中,我会使用TempData来实现这一点。在方法的第一次加载时,您可以在TempData中设置一个值,以便在下一次加载(刷新)时设置一个值。

假设您有一个Add方法,我认为应该这样做:

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);
        }

答案 2 :(得分:1)

将此脚本添加到您的头部:

<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>

在服务器端,只检查Request [“f5”] ==“1”

如果您不想修改URL,可以添加临时cookie。像这样的东西:

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

在页面加载时检查cookie是否存在并将其删除以用于下一个请求。

答案 3 :(得分:0)

您可以将当前会话ID与最后加载的页面进行比较,然后比较IsPostBack命令。

如果IsPostBack为true,您知道用户点击了该页面上的内容以将页面发回。 如果为当前会话ID检索的最后一页与您当前加载的页面不同,则他们从另一页面到达此页面。 如果检索到的最后一页与当前正在处理的当前页面的会话ID相同,则可能是刷新(F5)。

唯一的问题是你会检测到F5与将光标放在地址栏中的人一样,并在页面加载完成后点击Enter键,但我怀疑这对你来说是个问题。

编辑: 关于这个系统如何运作的评论似乎有些混乱所以让我进一步解释。正如我所指出的那样,IsPostBack在MVC中不可用,所以你必须测试后退,如下所示:

ASP.NET MVC - Is IsPostBack still here?

让我们考虑一下您可以在页面,任何页面上结束的三种方式。对于我们的示例,让我们假设我们想要检测第X页上的刷新。

您可以通过以下方式访问Page X: 1.用户按下第A页上的按钮,将您带到第X页。 2.用户按下页面B上的按钮,将您发回到页面B(回发后)。 3.用户按F5或以其他方式重新加载页面。 - 这是我们想要检测的......

有方案4,用户从另一个网站来到第X页&#39;但这会开始一个新的会议,所以我们不要考虑这个。

每次用户加载页面时,您都会将该页面与SessionID一起存储在某处。在会话超时期间,SessionID对于任何一个用户都是常量。这有一些注意事项,例如在一台机器上从不同的浏览器访问,但我不想混淆问题。

场景1: 用户加载页面A,我们查看内存,目前没有记录。我们存储&#39; Page A&#39;和内存中的sessionID。 用户单击页面A上的按钮。 用户被重定向,发布或转移到页面B. 页面B加载,我们检查&#39; IsPostBack&#39;旗帜,此时可能是也可能不是。如果我们知道它不是刷新,如果它是假的,我们需要继续测试如下。我们看着我们的记忆,并且有一个记录的页面A&#39;对于当前的会话ID(请记住,会话ID在任何给定用户的请求之间不会发生变化)。 因为上一页是“Page A&#39;我们在页面B上,我们知道这不是一个刷新。 我们存储&#39; Page B;和sessionID在内存中(实际上我们要么擦除或更新指向页面A的前一条记录)。

场景2: 用户加载页面B,我们存储&#39;页面B&#39;和内存中的sessionID。 用户单击第B页上的按钮。 页面B加载,我们检查'IsPostBack&#39;旗。确实如此,我们知道这不是一次更新。

场景3: 用户加载页面B,我们存储&#39;页面B&#39;和内存中的sessionID。 用户刷新页面或通过将光标放在地址栏中并按Enter键重新加载页面。 页面B加载,我们检查&#39; IsPostBack&#39; flag,这是假的,所以我们需要继续测试如下。我们在记忆中看到了“B&B”的记录。对于当前的会话ID。因为上一页是“Page B&#39;我们在页面B上,我们知道这是一个刷新。

通过使用此方法,您可以检测刷新。如果您使用MVC,则可以测试Request.HttpMethod=="POST"

您遇到的唯一问题是,如果用户执行POST,您进行重定向,那么用户返回一页并刷新,将重新提交表单,再次发送POST。当它实际上是刷新时,这将被检测为新提交。这可以使用Nonce方法或类似方法来消除。