我必须在我的网站上添加一个页面,该页面可以通过POST请求进行访问。该请求没有副作用,因此用户可以安全地使用其页面上浏览器的“刷新”按钮。之所以必须是POST而不是GET的原因是,表征请求所需的数据量很大(它包含任意多个GUID的集合,这些GUID标识了将在该过程的后续阶段进行操作的资源)。
当浏览器的用户刷新作为POST请求结果的页面时,浏览器通常会警告他们,该表单将被重新提交,并可能导致重复操作。在这种情况下,这不是问题,因为正如我所说,请求此页面的操作没有副作用。因此,我想与用户的浏览器交流,如果用户使用“刷新”功能,则不应向用户显示此类警告。我怎样才能做到这一点?
您不能阻止浏览器警告用户有关重新提交POST请求的信息。
参考资料
Mozzila论坛(Firefox的前身)从2002年开始广泛讨论了该功能。还出现了其他浏览器的一些讨论。很明显,已决定执行该功能,尽管建议了解决方法,但并未采取措施。
Google Chrome(2008)和其他后续浏览器也包含此功能。
造成这种情况的原因涉及到的区别GET和POST在RFC2616:超文本传输协议- HTTP / 1.1(1999年)。
检索Request-URI标识的任何信息
请求原始服务器接受请求中包含的实体作为资源的新下属
这表明,虽然GET请求仅检索数据,但POST请求以某种方式修改了数据。根据Mozilla论坛上的讨论,决定是禁用警告会给用户带来更大的风险,而不是保留警告带来的不便。
解决方案
相反,一种解决方案是使用会话将数据存储在POST请求中,然后将具有GET请求的用户重定向到在会话数据中查找原始请求参数的URL。
假设服务器端应用程序具有会话支持并已启用。
POST /results
GET /results
如果用户刷新页面,则重复步骤4和5。
为了使解决方案更加可靠,可以将POST数据分配给唯一键,该键作为302重定向中的路径或查询的一部分传递GET /results?set=1
。这样将可以查看和刷新多个不同的页面,例如在不同的浏览器选项卡中。必须考虑确保唯一密钥有效并且不允许访问其他会话数据。
某些系统,如Kibana,Grafana,pastebin.com和许多其他系统,则走得更远。POST请求值存储在持久性数据存储中,并且唯一的短URL提供给用户。短URL可以在GET请求中使用,并可以与其他用户共享,以查看与原始POST请求相同的结果。
“服务器识别传入的GET请求正在请求上一个POST请求的结果” -除了存储数据并为其分配唯一密钥外,如何处理?
“您不能阻止浏览器警告用户有关重新提交POST请求的信息。” - 为什么不?您可以引用消息来源进行备份吗?目前,这被认为是不可能的,因为您说的是。
@Hammerite,一个好问题。很难提供消息来源,因为我不知道任何一种官方要求。这是浏览器开发人员产生的功能。但是请考虑一下Chrome忽略了
autocomplete
,这表明即使指示浏览器执行某项操作,也不一定总是符合要求。