HTTP重定向是通过HTTP代码301和302(也可能是其他代码)以及带有新位置的地址的称为“位置”的标头字段完成的。但是,浏览器始终向该URL发送“ GET”请求。
但是,很多时候您需要通过POST(例如银行付款)将用户重定向到另一个域。这是一个常见的场景,并且确实是一个要求。有人知道为什么HTTP规范中忽略了这样的通用要求吗?解决方法是将表单(带有隐藏字段中的参数)的操作发送到目标位置(Location标头字段的值),然后setTimeout
将表单提交到目标位置。
HTTP重定向是通过HTTP代码301和302(也可能是其他代码)以及带有新位置的地址的称为“位置”的标头字段完成的。但是,浏览器始终向该URL发送“ GET”请求。
但是,很多时候您需要通过POST(例如银行付款)将用户重定向到另一个域。这是一个常见的场景,并且确实是一个要求。有人知道为什么HTTP规范中忽略了这样的通用要求吗?解决方法是将表单(带有隐藏字段中的参数)的操作发送到目标位置(Location标头字段的值),然后setTimeout
将表单提交到目标位置。
Answers:
在HTTP 1.1中,实际上存在一个状态码(307),该状态码指示应使用相同的方法并发布数据来重复该请求。
正如其他人所说的那样,这里有可能被滥用,这可能就是为什么许多框架在其抽象中坚持使用301和302的原因。但是,通过适当的理解和负责任的使用,您应该能够完成所需的工作。
请注意,根据W3.org规范,如果METHOD
不是HEAD
或GET
,则用户代理应提示用户,然后在新位置重新执行请求。您还应该为用户提供注释和备用机制,以防旧的用户代理不确定如何处理307。
使用这种形式:
<form action="Test307.aspx" method="post">
<input type="hidden" name="test" value="the test" />
<input type="submit" value="test" />
</form>
让Test307.aspx只需在以下位置返回307:http : //google.com,Chrome 13和Fiddler确认“ test = the test”确实已发布到Google。当然,进一步的响应是405,因为Google不允许发布POST,但它显示了机制。
有关更多信息,请参见HTTP状态代码列表和W3.org规范。
307临时重定向(自HTTP / 1.1起)在这种情况下,应使用另一个URI重复该请求,但是以后的请求仍可以使用原始URI。2与303相反,重新发出原始请求时,不应更改请求方法。例如,必须使用另一个POST请求重复POST请求。
WWW上最简单的情况是“幂等”事务,即可以重复而不会造成任何损害的事务。这些通常是“ GET”事务,这是因为它们是直接的URL引用(例如HTML中的href =或src =属性)的检索,或者是它们是使用GET方法提交的表单。重定向这样的事务很简单,没有任何问题:客户端接收到重定向响应,其中包括指定新URL的Location:标头,并且客户端通过将事务重新发布到新URL来对此做出反应。与这些重定向相关联的不同30x状态代码之间在隐式可缓存性方面有所不同,但是在其他方面,它们对于GET请求的响应基本相似(301和302)。
POST事务是不同的,因为从原则上讲,它们被定义为非等幂的(例如订购比萨饼,进行表决或进行其他操作),并且不得任意重复。
HTTP协议规范旨在考虑这种区别:GET方法定义为固有幂等,而POST方法至少定义为非幂等;该规范要求客户端代理(例如浏览器)采取多种预防措施,以防止用户无意间(重新)提交他们不想要的POST事务,或将POST提交到他们不希望的上下文中。
尽管我不喜欢从技术上限制用户的使用,以防止用户造成不必要的混乱或对应用程序造成不必要的伤害,但我可以理解这一点,这很有意义。
GET(和其他一些方法)在http规范(RFC 2616)中定义为“ SAFE” :
9.1.1安全方法
实施者应注意,该软件在通过Internet进行的交互中代表用户,并应小心谨慎,以使用户知道他们可能采取的任何对自己或他人而言具有意想不到的意义的动作。
特别是,已经建立了约定,即GET和HEAD方法不应具有除检索之外的其他任何操作。这些方法应该被认为是“安全的”。这允许用户代理以特殊方式表示其他方法,例如POST,PUT和DELETE,以便使用户知道请求了可能不安全的操作这一事实。
自然地,不可能确保服务器不会由于执行GET请求而产生副作用;实际上,一些动态资源认为该功能。这里的重要区别是用户没有要求副作用,因此不能对它们负责。
这意味着,除了看到他们可能不想看到的内容外,GET请求对用户永远不会有任何严重的后果,但是POST请求可能会更改对他们或其他人重要的资源。
尽管JavaScript改变了这种情况,但传统上用户界面有所不同-用户可以通过单击链接来触发GET请求,但必须填写表单来触发POST请求。我认为HTTP的设计者渴望维护安全和非安全方法之间的区别。
我也认为没有必要重定向到POST。大概需要执行的任何操作都可以通过在服务器端代码中调用一个函数来完成,或者如果它需要在其他服务器上发生,则可以将包含浏览器URL的重定向发送到服务器,而不是发送重定向到该服务器可以向该服务器本身发出请求,就像用户的代理一样。