搜索

2010年12月15日星期三

HTTP 1.1 中的跳转

跳转者,从一个 URI 跳到另一个 URI 而已,本来没什么好说的,最近没事儿,打算研读一下 HTTP 协议,发现其中居然大有名堂,胡乱堆在这里,看看有没有帮助(其实好多自己也没弄明白)。

HTTP 1.1 协议中关于跳转的代码有:
  • 300 Multiple Choices
  • 301 Moved Permanently
  • 302 Found
  • 303 See Other
  • 307 Temporary Redirect
其中,经常被误提及的说法:301代表永久跳转,302代表临时跳转,其它代码似乎鲜为人知?!

下面是我的理解:

这些代码都表示跳转,不同的代码标示其语义信息。

HTTP 1.1 协议中提及,1xx, 2xx, 3xx, 4xx, 5xx 这类代码,必须支持的代码仅仅是 100, 200, 300, 400, 500 其它代码属于可选,且遇到非00结尾的代码时,应用可以推定为等于该类的00代码。所以,通用的理解,300等于跳转,如果你需要跳转,且跳转情况不属于任何3xx代码的范畴,那么可以安全的使用300代码。

301 没有任何歧义,永久跳转,聪明的代码会把未来的访问都改成新 URI。

302 在 HTTP 1.0 中曾被用于表示临时跳转,不过在 1.1 中已经变成了 found(找到)。我的理解是,客户端给出了一个错误的 URI,但是该 URI 的信息足以供服务器检索到实际 URI,所以会跳转到检索结果去;但是因为这是推定结果,所以未来的访问依旧采用原 URI,302 码也说明了这个结果是推定结果,不一定精确等于原来请求的资源。

303 类似 302,但是被检索到的结果不是客户端请求结果,而是该请求的相关资源。例如,客户端请求查询青蛙的信息,但是服务器上找不到青蛙的信息,但是比较好的返回是给出一个两栖动物的页面。

307 某资源临时办到新 URI,过一阵子会搬回来的,这才是临时跳转。(目前302被广泛滥用,其实大多数情况,真正正确的代码应该是307)

官方论述参见 HTTP 1.1:http://www.rfc-editor.org/rfc/rfc2616.txt 上面的解释不是原文翻译,而是我的理解,可能有误。顺便说一句,原文太晦涩了,尤其是 302 和 307 原文中居然没有任何差别,它们只有解释短语的差别(Reason Phrase)。

上面论述是基于规范原文做原教旨主义分析,目前各搜索引擎处理方式不一,包括谷歌。

补充一下为什么 HTTP 1.1 协议中限制 303 跳转时,请求方法只能为 GET:

因为 303 表示返回结果为请求 URI 的“相关”结果,而不是被请求结果本身,所以当然就只能以只读方式返回。

例如,请求青蛙的页面,但是服务器上没有青蛙页面,于是返回一个相关 (see other) 页(例如两栖动物页面)。但是原请求是修改青蛙页面的某信息,那么显然跳转之后,显然不可以把本来用户编辑青蛙页面的操作,直接应用到两栖动物页面上,所以访问方法被修改为 GET (只读)。

没有评论:

发表评论