http3xx重定向状态码

http3xx 重定向状态码

简单说下 301/302/303/307/308 这 5 种状态码的情况

状态码的解释

301 Moved Permanently(永久移动)

被请求的资源已永久移动到新位置,并且将来任何对此资源的引用都应该使用本响应返回的若干个 URI 之一。如果可能,拥有链接编辑功能的客户端应当自动把请求的地址修改为从服务器反馈回来的地址。
除非额外指定,否则这个响应也是可缓存的。新的永久性的 URI 应当在响应的Location域中返回。
除非这是一个 HEAD 请求,否则响应的实体中应当包含指向新的 URI 的超链接及简短说明。如果这不是一个 GET 或者 HEAD 请求,因此浏览器禁止自动进行重定向,除非得到用户的确认,因为请求的条件可能因此发生变化。

注意:对于某些使用 HTTP/1.0 协议的浏览器,当它们发送的 POST 请求得到了一个 301 响应的话,接下来的重定向请求将会变成 GET 方式。

302 Found(发现)

要求客户端执行临时重定向(原始描述短语为“Moved Temporarily”)。由于这样的重定向是临时的,客户端应当继续向原有地址发送以后的请求。
只有在Cache-ControlExpires中进行了指定的情况下,这个响应才是可缓存的。新的临时性的 URI 应当在响应的Location域中返回。
除非这是一个 HEAD 请求,否则响应的实体中应当包含指向新的 URI 的超链接及简短说明。如果这不是一个 GET 或者 HEAD 请求,那么浏览器禁止自动进行重定向,除非得到用户的确认,因为请求的条件可能因此发生变化。

注意:虽然 RFC 1945 和 RFC 2068 规范不允许客户端在重定向时改变请求的方法,但是很多现存的浏览器将 302 响应视作为 303 响应,并且使用 GET 方式访问在 Location 中规定的 URI,而无视原先请求的方法。因此状态码 303 和 307 被添加了进来,用以明确服务器期待客户端进行何种反应。

303 See Other(查看其他)

对应当前请求的响应可以在另一个 URI 上被找到,当响应于 POST(或 PUT / DELETE)接收到响应时,客户端应该假定服务器已经收到数据,并且应该使用单独的 GET 消息发出重定向。这个方法的存在主要是为了允许由脚本激活的 POST 请求输出重定向到一个新的资源。这个新的 URI 不是原始资源的替代引用。同时,303 响应禁止被缓存。当然,第二个请求(重定向)可能被缓存。新的 URI 应当在响应的 Location 域中返回。除非这是一个 HEAD 请求,否则响应的实体中应当包含指向新的 URI 的超链接及简短说明。注意:许多 HTTP/1.1 版以前的浏览器不能正确理解 303 状态。如果需要考虑与这些浏览器之间的互动,302 状态码应该可以胜任,因为大多数的浏览器处理 302 响应时的方式恰恰就是上述规范要求客户端处理 303 响应时应当做的。

307 Temporary Redirect(临时重定向)

在这种情况下,请求应该与另一个 URI 重复,但后续的请求应仍使用原始的 URI。 与 302 相反,当重新发出原始请求时,不允许更改请求方法。 例如,应该使用另一个 POST 请求来重复 POST 请求

308 Permanent Redirect (永久重定向)

请求和所有将来的请求应该使用另一个 URI 重复。 307 和 308 重复 302 和 301 的行为,但不允许 HTTP 方法更改。 例如,将表单提交给永久重定向的资源可能会顺利进行。

301/302/303/307/308 的区别

301,302 是 http1.0的内容,303、307、308 是 http1.1的内容。

301 和 302 本来在规范中是不允许重定向时改变请求方法的(将 POST 改为 GET),但是许多浏览器却允许重定向时改变请求方法(这是一种不规范的实现)。

303 的出现正是为了给上面的 301,302 这种行为作出个规范(将错就错吧),也就是允许重定向时改变请求方法。此外 303 响应禁止被缓存。

大多数的浏览器处理 302 响应时的方式恰恰就是上述规范要求客户端处理 303 响应时应当做的,所以 303 基本用的很少,一般用 302

307 和 308 的出现也是给上面的行为做个规范,不过是不允许重定向时改变请求方法。

Permanent Temporary
Allows changing the request method from POST to GET. 301 302
Does not allow changing the request method from POST to GET. 308 307

注:永久(Permanent)和临时(Temporary)的区别

永久是指原来访问的资源已经永久删除啦,客户端应该根据新的 URI 访问重定向。

临时是指访问的资源可能暂时先用 location 的 URI 访问,但旧资源还在的,下次你再来访问的时候可能就不用重定向了。

故 301 与 302 的区别:

301 表示搜索引擎在抓取新内容的同时也将旧的网址交换为重定向之后的网址;302 表示旧地址 A 的资源还在(仍然可以访问),这个重定向只是临时地从旧地址 A 跳转到地址 B,搜索引擎会抓取新的内容而保存旧的网址。

使用场景

因为 301 与 302 的区别,所以导致产生 302 网址劫持,故不建议使用 302 重定向(然而浏览器默认是使用 302 重定向)

302 重定向和网址劫持(URL hijacking)

从网址 A 做一个 302 重定向到网址 B 时,主机服务器的隐含意思是网址 A 随时有可能改主意,重新显示本身的内容或转向其他的地方。大部分的搜索引擎在大部分情况下,当收到 302 重定向时,一般只要去抓取目标网址就可以了,也就是说网址 B。如果搜索引擎在遇到 302 转向时,百分之百的都抓取目标网址 B 的话,就不用担心网址 URL 劫持了。问题就在于,有的时候搜索引擎,尤其是 Google,并不能总是抓取目标网址。比如说,有的时候 A 网址很短,但是它做了一个 302 重定向到 B 网址,而 B 网址是一个很长的乱七八糟的 URL 网址,甚至还有可能包含一些问号之类的参数。很自然的,A 网址更加用户友好,而 B 网址既难看,又不用户友好。这时 Google 很有可能会仍然显示网址 A。由于搜索引擎排名算法只是程序而不是人,在遇到 302 重定向的时候,并不能像人一样的去准确判定哪一个网址更适当,这就造成了网址 URL 劫持的可能性。也就是说,一个不道德的人在他自己的网址 A 做一个 302 重定向到你的网址 B,出于某种原因, Google 搜索结果所显示的仍然是网址 A,但是所用的网页内容却是你的网址 B 上的内容,这种情况就叫做网址 URL 劫持。你辛辛苦苦所写的内容就这样被别人偷走了。302 重定向所造成的网址 URL 劫持现象,已经存在一段时间了。不过到目前为止,似乎也没有什么更好的解决方法。在正在进行的谷歌大爸爸数据中心转换中,302 重定向问题也是要被解决的目标之一。从一些搜索结果来看,网址劫持现象有所改善,但是并没有完全解决。

使用 301 的场景:(一般是资源位置永久更改)

1.域名到期不想续费(或者发现了更适合网站的域名),想换个域名。

2.在搜索引擎的搜索结果中出现了不带 www 的域名,而带 www 的域名却没有收录,这个时候可以用 301 重定向来告诉搜索引擎我们目标的域名是哪一个。

3.空间服务器不稳定,换空间的时候。

注:另外,返回 301 请求码进行跳转被谷歌认为是将网站地址由 HTTP 迁移到 HTTPS 的最佳方法(然而大家都用 302。。。。)

使用 302 的场景:(一般是普通的重定向需求:临时跳转)

1.未登录前先使用 302 重定向到登录页面,登录成功后再跳回到原来请求的页面

举个例子,比如我未登录京东前我就访问京东的个人界面 https://home.jd.com/ ,然后就会重定向到登录界面,我们可以通过浏览器的 dev-tool 查看状态码

我们可以发现响应的状态码为 302,并且返回了 location 为登录界面的 url,并且附带了 ReturnUrl 方便我们登录后跳回到 https://home.jd.com/

2.有时候需要自动刷新页面,比如 5 秒后回到订单详细页面之类。

例子略。

3.有时系统进行升级或者切换某些功能时,需要临时更换地址。

例子略。

4.像微博之类的使用短域名,用户浏览后需要重定向到真实的地址之类。
再来个例子,我访问了另一个微博的秒拍视频链接:http://t.cn/RuOcwxn,然后重定向了两次,先是301重定向到video.weibo.com,再302重定向到miaopai.com。

5.电脑端与移动端的转换

比如我访问网页端页面https://www.taobao.com/,302重定向到了移动端页面m.taobao.com

使用 303 的场景

几乎没有,一般就是用 302

使用 307 的场景

很少用,与 302 类似,只不过是针对 POST 方法的请求不允许更改方法

不过我在访问百度时,发现用了 307 状态码

使用 308 的场景

很少用,与 301 类似,只不过是针对 POST 方法的请求不允许更改方法

参考

详解重定向(HTTP 状态码 301/302/303/307/308)附例子