【问题标题】:Is it possible to detect a page refresh (F5) serverside?是否可以检测到页面刷新(F5)服务器端?
【发布时间】:2013-10-16 20:11:18
【问题描述】:

...与正常链接点击行为的请求相比。我想我也许可以用它来丢弃服务器端的一些缓存内容。对于更注重技术的目标受众来说,这可能是一种相对自然的方式来清除图形和图表的缓存。

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

【问题讨论】:

  • 使用正常的缓存过期规则/策略。您可以检查从客户端发送的缓存/etag 标头并做出相应的反应 - 但最简单的说法可能是 if 获取此资源,然后重新生成它,否则依赖客户端正确遵守缓存标头已发送。
  • 你关心刷新和再次请求相同页面之间的区别吗?
  • 也许这有帮助:superuser.com/questions/17464/…

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


【解决方案1】:

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

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

我刚刚通过在所有三个浏览器中刷新此页面并检查 Fiddler 来检查这一点。可能还有更复杂的逻辑在发生,而我还没有理解。

【讨论】:

  • 在 IE 11 中尝试过,它没有在 Request.Headers 中添加“Pragma: no-cache”(在 Visual Studio 中检查了请求)
【解决方案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);
        }

【讨论】:

    【解决方案3】:

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

    <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 是否存在并将其删除以供下次请求。

    【讨论】:

    • 您提到:“与正常链接点击行为的请求相比。”。所以点击地址栏并按回车将是一个正常的链接点击。
    • 那又怎样?作者谈到了F5。符合要求
    【解决方案4】:

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

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

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

    编辑: cmets 似乎对这个系统的工作方式有些困惑,所以让我进一步解释一下。正如向我指出的那样,IsPostBack 在 MVC 中不可用,因此您必须测试回发,如下所示:

    ASP.NET MVC - Is IsPostBack still here?

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

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

    场景 4 是“用户从另一个站点来到页面 X”,但这会启动一个新会话,所以我们不要考虑这个。

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

    场景 1: 用户加载页面A,我们查看内存,目前没有记录。我们将“Page A”和 sessionID 存储在内存中。 用户单击页面 A 上的按钮。 用户被重定向、发布或转移到页面 B。 页面 B 加载后,我们检查“IsPostBack”标志,此时它可能为真,也可能不是。如果是我们就知道不是刷新,如果是假的我们需要继续测试如下。我们在内存中查找当前会话 ID 的“页面 A”记录(请记住会话 ID 在任何给定用户的请求之间不会更改)。 因为上一页是“页面 A”,而我​​们在页面 B,我们知道这不是刷新。 我们存储'Page B;以及内存中的 sessionID(实际上我们要么删除要么更新指向页面 A 的先前记录)。

    场景 2: 用户加载页面 B,我们将“页面 B”和 sessionID 存储在内存中。 用户单击页面 B 上的按钮。 页面 B 加载,我们检查“IsPostBack”标志。这是真的,所以我们知道这不是刷新。

    场景 3: 用户加载页面 B,我们将“页面 B”和 sessionID 存储在内存中。 用户通过将光标放在地址栏中并按 Enter 来刷新页面或重新加载页面。 页面B加载,我们检查'IsPostBack'标志,它是假的,所以我们需要继续测试如下。我们在内存中查找当前会话 ID 的“页面 B”记录。因为上一页是“页面 B”,而我们在页面 B 上,所以我们知道这是一次刷新。

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

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

    【讨论】:

    • SessionId 不会更改,除非用户会话结束或您管理会话以根据每个请求进行更改。
    • 是的,就是这样。您知道会话 ID 不会更改,因此您可以使用它来了解两个连续请求是否来自同一用户。
    • 克雷格,我想你误会了。会话 ID 不会帮助您区分初始请求和刷新。会话 ID 将相同。答案和回应是荒谬的。另外,IsPostBack 不存在于 MVC 中。只有你的最后一点是相关的;很难区分刷新和另一个 url 请求。这就是重点。
    • 我不知道 isPostBack 在 MVC 中不存在,它确实在 WebForms 中工作,尽管我目前使用这种方法。
    • 我已经扩展了我的回复以进一步解释并尝试消除使用此方法的明显混淆。
    猜你喜欢
    • 2018-10-06
    • 2010-11-13
    • 2012-05-03
    • 2011-02-25
    • 2020-11-11
    • 2011-05-13
    • 2012-04-25
    • 2011-02-21
    • 1970-01-01
    相关资源
    最近更新 更多