谈HTTP状态码应用–3XX

2012年4月2日 发表评论 阅读评论

http://koda.javaeye.com/blog/463834

 

重定向是一个看似简单,实际很复杂的问题。HTTP状态码一共才五个系列(1XX,2XX,3XX,4XX,5XX),而重定向状态码被单独作为一个系列(3XX)存在,足以说明它的重要性,但是很多人认为知道301/302的区别就算熟悉重定向了,这实在是一大谬误。本文主要介绍一下303/307。

为了方便测试,首先熟悉一下如何使用curl命令得到响应头:

引用
-I/–head
    (HTTP/FTP/FILE) Fetch the HTTP-header only! HTTP-serversfeature the command HEAD which this uses to get nothing but the headerof a document. When used on a FTP or FILE file, curl displays the filesize and last modification time only.

例子命令:curl -I http://www.google.com/

通常PHP里的重定向是这样的:

Php代码

header(‘Location: http://localhost/’);  exit();  

header(‘Location: http://localhost/’);exit();

通过curl命令访问如上的代码,我们将得到如下响应头:
HTTP/1.1 302 Found
Location: http://localhost/

如上的重定向代码在编程里很常用,比如说添加文章成功后,跳转回列表页,不过这里的重定向状态码302却是值得商榷的。

这还得从头说起,在HTTP1.0的时代,那时候302的名字还是“MovedTemporarily”,

但在实际使用上,302往往包含了两方面的意思(也就是后来的303/307),

为了消除可能的混淆,在HTTP1.1中,302被重命名为“Found”,

并新加了303(See Other)和307(TemporaryRedirect),

至于PHP之所以在重定向时缺省使用302状态码是为了兼容的目的,

所以不到不得已(有时候,客户端是HTTP1.0的,只理解302),不应该使用302。

303和307都把重定向的URI置于Location头中,他们的区别在于:

引用
303:对于POST请求,它表示请求已经被处理,客户端可以接着使用GET方法去请求Location里的URI。
307:对于POST请求,表示请求还没有被处理,客户端应该向Location里的URI重新发起POST请求。

下面看看PHP如何发送非302的重定向,以303为例:

Php代码

// 第一种方法  header(‘Location: http://localhost/’, true, 303);  

// 第一种方法header(‘Location: http://localhost/’, true, 303);

Php代码

// 第二种方法  header(‘HTTP/1.1 303 See Other’);  header(‘Location: http://localhost/’);  

// 第二种方法header(‘HTTP/1.1 303 See Other’);header(‘Location: http://localhost/’);
使用curl命令,你就会看到如下响应头:

HTTP/1.1 303 See Other
Location: http://localhost/

总结,本文说的主要是303/307之间的关系。之所以明确区分是为了让状态码本身能够准确的表达响应的含义,从而尽可能的避免对重定向的滥用。

下面是303和307的一个可能的具体应用:
//form.html

Html代码

<form action="save.php" method="post">      <input type="text" name="username" value="Allen Guo">      <input type="submit" value="SUBMIT">  </form>  

<form action="save.php" method="post"> <input type="text" name="username" value="Allen Guo"> <input type="submit" value="SUBMIT"></form>
//save.php
<?php

Php代码

// 存储然后转向  $f = fopen(‘form.txt’,‘a’);  fwrite($f$_POST['username']);  fclose($f);    //header(‘Location: http://localhost/php/list.php’, true, 302);  //header(‘Location: http://localhost/php/list.php’, true, 307);  header(‘Location: http://localhost/php/list.php’, true, 303);  exit;  

// 存储然后转向$f = fopen(‘form.txt’,'a’);fwrite($f, $_POST['username']);fclose($f);//header(‘Location: http://localhost/php/list.php’, true, 302);//header(‘Location: http://localhost/php/list.php’, true, 307);header(‘Location: http://localhost/php/list.php’, true, 303);exit;

//list.php

Php代码

<h1>Back To List Page</h1>  <hr/>  <?php echo ‘USER NAME : ’ . $_POST['username']; ?>  

<h1>Back To List Page</h1><hr/><?php echo ‘USER NAME : ‘ . $_POST['username']; ?>

运行过程是:form.html->save.php->list.php
尝试不断切换save.php代码中的header状态码,看看有什么变化。切换到307的时候,list.php能获得$_POST['username'],而303/303不可以


转载请注明来自:[MSN Spaces]http://msn.shandian.biz/138.html

  1. 本文目前尚无任何评论.