301、302、303、307、308

本文最后更新于:1 年前

301、302、303、307、308

1、HTTP 状态码

HTTP 状态码是由 RFC2616 规范定义的,用以表示服务器超文本传输协议响应状态的 3 位数字代码。状态码是协助开发者掌握请求是否运转正常的一个标志,常见的大概有 200,304,404,500 等。每个状态码都有其代表的意义,而且也发挥着不同的作用。

有趣的状态码1

有趣的状态码2

2、HTTP 3xx

HTTP 状态码 3xx 一类的都是重定向(Redirect),需要进一步的操作以完成请求。

参考RFC7231 第六节

状态码 状态码名称 描述
300 Mutiple Choices 表示目标资源具有多种选择,用户或浏览器能够自行选择一个首选的地址进行重定向。
301 Moved Permanently 资源已被永久移动到新位置,服务器应生成一个 Location 字段,让用户代理可以使用此字段进行自动重定向。由于历史原因,用户代理可能会改变请求方法
302 Found 表示目标资源暂时驻留在其他 URI 下,由于重定向可能随时被更改,所以客户端应该继续使用有效请求。服务器应生成一个 Location 字段,让用户代理可以使用此字段进行自动重定向。由于历史原因,用户代理可能会改变请求方法
303 See Other 表示服务器需要将用户代理重定向至另一个资源,客户端会将请求方法改为 GET。与 302 类似,因为历史原因增加的状态码。大部分 HTTP/1.1 版以前的浏览器不能理解 303 状态。
304 Not Modified 表示客户端发送了一个带条件的 GET 或 HEAD 请求并且被允许,而且内容还是有效(自上次访问后根据请求的条件),则服务器应当返回这个状态码,并且禁止包含消息体
305 Use Proxy 表示被请求资源需要通过制定代理才能被访问,现已被弃用
306 Switch Proxy 已被弃用,但是保留状态码
307 Temporary Redirect 表示资源暂时被重定向到不同的位置,因为重定向随时会被改变,所以客户端应继续使用原始的有效请求。与 302 类似,只是不允许将请求方法从 POST 改为 GET
308 Permanent Redirect 这个跟 301 差不多,只是不允许将请求方法从 POST 改为 GET(RFC7238

3、各大网站的重定向

在日常浏览网页的时候,如果有心观察请求,有时候会发现一些页面返回的是 301 或者 302。

engadaget

google

jd

xiaomi

还能看到一些 307 的:

taobao

(讲道理淘宝前几天还是 302)

youtube

4、实际应用场景

上面了解到了部分 3xx 状态码的意义,但是还是不知道是用来做什么的。其实 301 和 302 看起来效果是一样的,对于浏览器来说都会去重新对 Location 字段请求。这个过程可以称之为重定向,表现为用户在地址栏输入的地址 A,瞬间变成了地址 B。

4-1、为什么需要重定向

正常来说,浏览网站就浏览了,为什么需要重定向到另一个地址呢?一般来说分为以下几种情况:

  • 网站域名更改(例如 xiaomi.com 变成 mi.com)
  • 网站路径更改(例如页面路径更改,扩展名更改等)
  • 网站协议更改(例如 http 的页面需要跳到 https)
  • 多个域名,需要将流量和权重综合到主站上

以上几种情况可以总结为,就是地址更改了,但是原地址都需要跳转到新地址上。如果没有重定向,用户的历史记录或者收藏夹或者搜索引擎的数据库中都只会得到一个 404 错误页面,让访问量白白流失,或者是某些注册了多个域名的网站,需要通过重定向让用户自动跳转到主站点。这时候就都需要用到重定向了。

4-2、关于 PR

对于普通浏览,其实 301 和 302 看起来是一样的,但是对于搜索引擎来说就完全不一样了,在此之前要科普一个名词叫PR

PR全称为 PageRank,级别是 0 到 10,是一个用以评测网页等级和重要性的一个指标。简单来说,PR 值越高,网页越受欢迎,或者说越重要,但是根据 Google 官方所说,PR 并不能对网站排名产生绝对作用。但是高 PR 值会被:

  • 收录更多的页面
  • 搜索引擎 spider 会访问更频繁,新内容更快被收录
  • 重复内容会更容易被判断为原创
  • 排名进入初始子集几率更大

4-3、301 和 302

301 含义是永久性重定向,302 是暂时性重定向,这样看起来好像用 302 就可以了,但是无论是 Google 还是百度都建议用 301。那到底是有什么区别呢?

假如现在有两个页面分别是 A(xxx.com)和B(h5.xxxxx.com),而我们需要告诉搜索引擎B页面就是原来的A页面,这时候就需要重定向方式处理。

  • 返回 301:如果 A 页面原来就已经被搜索引擎收录了,那么当搜索引擎再次爬取到 A 页面时,因为获取到 301,这样就会知道以后再也没有 A 页面,搜索引擎会将原本 A 页面的排名权重(PR 值)转移到 B 页面上去,并且将数据库中 A 页面记录替换成 B 页面。
  • 返回 302:搜索引擎会觉得这次只是临时跳转,未来 A 页面随时可能改变跳转,重新显示原来内容或者跳转到其他地方,所以搜索引擎接收到 302 时,数据库并不会删除 A 页面,而是新建 B 页面的记录,A 页面的 PR 值也不会转移到 B 页面上去。

为什么建议用 301,一方面是 PR 的浪费问题,另一方面是 URL 劫持的问题。

实际上如果搜索引擎接收到 302 跳转时,永远都去抓取 Location 目标的话,就不会有这种问题了,正正是因为搜索引擎尤其是 Google,并不能总是有效抓取 Location,这是因为 Google 有自己的考虑在里面:当 B 页面的 URL 是个杂乱且冗长带各种参数的网址,而 A 页面却是简短且友好的话,Google 很有可能还是显示 A 网址。而这时候,一些人就会利用这一点,让自己的 C 页面返回 302 指向一个 内容质量较高的 D 页面,然后因为 Google 的这套机制,可能显示的搜索结果还是 C 但是内容却是 D 页面的内容了,这样子 D 页面的作者的辛苦写的东西都被窃取者偷走并作为自己的成果。这个就是 URL 劫持。

虽然 Google 对 302 问题很重视,URL 劫持现象还是有点改善,但是没有完全解决。而如果长时间用 302 作为长期跳转,搜索引擎会判定这个行为是作弊行为,302 也很容易被搜索引擎误认为是利用多个域名指向同一站点,会对页面给予惩罚,甚至封掉,挂上“利用重复内容干扰 Google 搜索结果的网站排名”。所以在使用网站重定向时,非必要不建议用 302。

4-4、不使用跳转的后果

一方面是搜索引擎会发现有新页 B 面进行收录,但是由于没有跳转,所以认为是个全新的页面,与原来的 A 网站无关联,所以 A 的页面 PR 不会传到给 B,如果原来 A 的 PR 值很高,B 页面却需要重新计算,这里就会很吃亏

另一方面则是如果搜索引擎访问 A 页面,由于没跳转发现的是 404 表示资源找不到,搜索引擎会认为网站没做好并且会给予惩罚,导致排名下降

5、 PR 劫持

大概原理其实是利用了 301 或 302 跳转,把自己的网站 A 重定向至高 PR 值网站 B,因为 B 网站的 PR 值较高,在 A 网站 PR 值更新后,也会显示成 B 网站的 PR 值。利用这点,A 网站得到了本不属于自己的高 PR,并且在更新了 PR 后,立刻取消重定向,放上自己的内容。这样做,就会让浏览者误以为这个网站是个高 PR 值的网站。而本次 PR 劫持至少能持续到下一次 PR 值更新,大概会有 2~3 个月。

更隐晦一点的做法是,通过请求检测到本次为搜索引擎的 spider 时,返回 301 指向高 PR 值网站,却对普通浏览者返回原本页面,这样子做,甚至可以不影响自己的内容的前提下劫持了高 PR 值的网站。

6、那 303、307、308 是怎么回事

通过上面的介绍可以知道,重定向的意义和对 seo 的影响,然后会发现 303、307、308 似乎跟 301 和 302 也差不多,但是又有所不同,然后网页的重定向返回码也各有不同,其实可以做个归类:

永久性重定向 暂时性重定向
允许更改请求方法 301 302、303
不允许更改请求方法 308 307

6-1、302 和 303 和 307

其实 303 可以理解为 302 的规范化版本,307 则是原本的 302 规范。在最初的 302 定义中,内容与现在的 307 意义,不允许重定向方法改写,但是早期的浏览器实现的时候,有些实现成现在的 303(允许更改请求方法),有些实现成现在的 307(不允许更改请求方法),于是乎之后的标准,就将 302 某些错误的实现写入规范成为了 303,而 302 原本的规范复制到了 307。在最近的一次修订中,302 标准不再强制需要维持原来请求方法,所以产生了现在的 302、303 和 307。

参阅 RFC7231:(中间这个MAY很关键,在 307 规范中为 MUST NOT
Note: For historical reasons, a user agent MAY change the request method from POST to GET for the subsequent request. If this behavior is undesired, the 307 (Temporary Redirect) status code can be used instead.

6-2、301 和 308

和 302 一样,301 在浏览器实现和标准有不一致问题,一直延续到了 2014 年的 RFC7231,所以后面标准补充了 308.

参阅 RFC7231:(也是MAY,表明协议也妥协了实现)
Note: For historical reasons, a user agent MAY change the request method from POST to GET for the subsequent request. If this behavior is undesired, the 307 (Temporary Redirect) status code can be used instead.


本博客所有文章除特别声明外,均采用 CC BY-SA 4.0 协议 ,转载请注明出处!