Safari和Chrome不完全支持307 Temporary Redirect
本文按署名·非商业用途·保持一致授权作者:
,发表于2008年12月06日13时41分
今天想实现一个功能:POST到某个url,如果符合某些条件,就把所有的请求再转发到一个新的url。而且这个二次请求必须让客户端来完成,还尽量不能依靠Javascript。
如果是要转发GET请求,那就简单了,301,302等等都可以实现,但是现在是要转发POST请求。我阅读了RFC 2616之后,发现307 Temporary Redirect是可以实现我的需求的。
整个过程是这样的:
#1 客户端发送POST请求到服务器
#2 服务器返回307的状态码,并指定一个名为Location的header
#3 客户端检测到307,于是把刚才发送的数据,原封不动地发送到Location所指定的url
但是经过测试之后,我发现Safari和Chrome都不支持对POST进行307 Temporary Redirect,而Firefox,Opera,IE6,IE7,IE8是支持的。支持转发POST的浏览器里,Firefox和Opera是最遵循标准的。在RFC2616里有一句:”If the 307 status code is received in response to a request other than GET or HEAD, the user agent MUST NOT automatically redirect the request unless it can be confirmed by the user”。就是说,如果不是GET或者HEAD请求,307转发之前必须得到用户的确认。IE5,6,7虽然支持转发,但是却不需要用户确认。不过IE的这个做法在可能带来安全性问题的同时,倒是提高了用户体验。而且我个人认为这也没降低什么安全性。如果一个网站想恶意利用用户的提交,办法很多,例如完全可以直接修改form的action或者用JS来实现一个转发。
需要测试的朋友可以访问,/jiaoben/307.php。点击go之后,如果浏览器支持对POST的307,那么会输出:
method:POST Array ( [x] => go )
否则会输出:
method:GET Array ( )
307.php的代码如下:
<?php
if (isset($_GET['r'])) {
echo 'method:',$_SERVER['REQUEST_METHOD'],'<br />';
print_r($_POST);
} else if ($_POST) {
header('HTTP/1.1 307 Temporary Redirect');
header('Location: 307.php?r=1');
} else {
?>
<form action="307.php" method="POST">
<input type="submit" name="x" value="go" />
</form>
<?php
}另外感谢一下几个朋友帮我做了windows下几款浏览器的测试。costi(chrome),阿宝(IE6),布雨的毛巾(IE7,IE8)。

2008-12-27 22:57:15
Opera 10 Alpha
会有个提示,提示用户现在会redirect一个POST。
确定后转发正常