您可以将当前会话 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 方法或类似方法来消除。