POST请求发送Refresh标头的位置使Firefox创建GET请求但仍保留POST数据

时间:2011-09-03 17:33:42

标签: http firefox

考虑以下代码;它基本上是一个通过HTTP POST发送一些数据的表单。当POST数据到来时,将发送Refresh HTTP标头。

<?php
if (!empty($_POST))
{
    header("Refresh: 5; URL=http://$_SERVER[SERVER_NAME]$_SERVER[REQUEST_URI]");
}
?>
<!doctype html>
<form method=post>
    <input type=hidden name=foo value=bar>
    <input type=submit>
</form>
<?php
echo "The location was requested using the HTTP $_SERVER[REQUEST_METHOD] method; \$_POST = ".var_export($_POST, 1);
?>

现在,这样做:

  1. 在Firefox浏览器中打开它(我创建了一个演示here;我在Debian上使用了6.0.1。)
  2. 提交表格。显然,浏览器执行了HTTP POST请求。请注意,Refresh HTTP标头附带响应。
  3. 等待5秒钟。现在正在应用Refresh标头,并且该位置将重定向到自身。
  4. Firefox执行了 GET 请求。它绝对是GET,因为Firebug和PHP的$_SERVER['REQUEST_METHOD']都说它。
  5. F5键。由于上次执行的HTTP请求是GET请求,因此可以预期来自先前请求的所有POST数据都将丢失。但是,会出现一个对话框,要求我重新发送POST数据:
  6.   

    要显示此页面,Iceweasel必须发送重复之前执行的任何操作(例如搜索或订单确认)的信息。

    所以,我的问题是 - 为什么POST数据仍在这里?这是一个错误还是预期的行为? 请注意,使用以下任何一项都会导致POST数据丢失(预期的行为):

    • Location标题代替Refresh
    • URL=标题Refresh参数的不同值(用户将被重定向到其他位置)。
    • 另一个浏览器(我测试过Internet Explorer 9.0.2和Chromium 6.0)。

1 个答案:

答案 0 :(得分:4)

这既不是错误,也不是预期的行为。原因是任何HTTP RFC都没有定义名为Refresh:的标头(最值得注意的是RFC1945RFC2616没有提到它)。这意味着,虽然大多数浏览器确实实现了Refresh标头,就好像它是元刷新一样,没有预期的行为可以假设在所有浏览器中都是相同的

环顾StackOverflowthe internet in general,看起来Refresh:标题(就像很多东西一样)是由Netscape在互联网早期发明并被大家采用的。虽然许多这些随意的Netscape设计(such as Javascript)后来被用作行业标准,但Refresh:标头却没有,因为HTTP已经使用3xx响应代码为此功能做好了准备。

不足之处在于,不同的浏览器以不同的方式处理它并不奇怪,因为没有标准可以告诉浏览器的开发人员如何处理它。关于在应用程序中使用标题 - 不要。干净利落。使用3xx重定向。这就是他们的目的。如果您因为需要在超时后刷新页面而使用它,请使用<meta>刷新 - while this is now officially deprecated它应该以相同的方式处理。