温馨提示:本文翻译自stackoverflow.com,查看原文请点击:http - How can I communicate to the user's browser that a POST request it made is side-effect-free?
browser http post side-effects

http - 如何向用户浏览器传达它发出的POST请求没有副作用的信息?

发布于 2020-04-10 10:52:14

我必须在我的网站上添加一个页面,该页面可以通过POST请求进行访问。该请求没有副作用,因此用户可以安全地使用其页面上浏览器的“刷新”按钮。之所以必须是POST而不是GET的原因是,表征请求所需的数据量很大(它包含任意多个GUID的集合,这些GUID标识了将在该过程的后续阶段进行操作的资源)。

当浏览器的用户刷新作为POST请求结果的页面时,浏览器通常会警告他们,该表单将被重新提交,并可能导致重复操作。在这种情况下,这不是问题,因为正如我所说,请求此页面的操作没有副作用。因此,我想与用户的浏览器交流,如果用户使用“刷新”功能,则不应向用户显示此类警告。我怎样才能做到这一点?

查看更多

提问者
Hammerite
被浏览
133
Steve E. 2020-02-06 06:39

您不能阻止浏览器警告用户有关重新提交POST请求的信息。

参考资料
Mozzila论坛(Firefox的前身)从2002年开始广泛讨论了该功能。还出现了其他浏览器的一些讨论。很明显,已决定执行该功能,尽管建议了解决方法,但并未采取措施。

Google Chrome(2008)和其他后续浏览器也包含此功能。

造成这种情况的原因涉及到的区别GETPOSTRFC2616:超文本传输协议- HTTP / 1.1(1999年)。

得到

检索Request-URI标识的任何信息

开机自检

请求原始服务器接受请求中包含的实体作为资源的新下属

这表明,虽然GET请求仅检索数据,但POST请求以某种方式修改了数据。根据Mozilla论坛上的讨论,决定是禁用警告会给用户带来更大的风险,而不是保留警告带来的不便。

解决方案
相反,一种解决方案是使用会话将数据存储在POST请求中,然后将具有GET请求的用户重定向到在会话数据中查找原始请求参数的URL。

假设服务器端应用程序具有会话支持并已启用。

  1. 用户提交带有生成特定结果的数据的POST请求 POST /results
  2. 服务器使用已知密钥将数据存储在会话中
  3. 服务器响应302重定向到选定的URL(可能是相同的URL)
  4. 客户端将使用GET请求来请求新页面 GET /results
  5. 服务器识别传入的GET请求正在请求先前的POST请求的结果,并使用已知密钥从会话中检索数据。

如果用户刷新页面,则重复步骤4和5。

为了使解决方案更加可靠,可以将POST数据分配给唯一键,该键作为302重定向中的路径或查询的一部分传递GET /results?set=1这样将可以查看和刷新多个不同的页面,例如在不同的浏览器选项卡中。必须考虑确保唯一密钥有效并且不允许访问其他会话数据。

某些系统,如Kibana,Grafana,pastebin.com和许多其他系统,则走得更远。POST请求值存储在持久性数据存储中,并且唯一的短URL提供给用户。短URL可以在GET请求中使用,并可以与其他用户共享,以查看与原始POST请求相同的结果。