HTTP重定向代码详解

301和302是最常见的重定向代码,其中301是永久重定向,302是临时重定向。它们的区别是永久重定向会被浏览器缓存,而临时重定向不会。除了常见的301和302,HTTP重定向代码还有303,307和308。

原理

在HTTP中,重定向是服务器发给客户端的响应,HTTP代码为3xx。在HTTP响应头中,Location字段标明了重定向的目的地址。
HTTP重定向图解

302临时重定向

HTTP重定向常用作从HTTP跳转到HTTPS。例如访问http://www.baidu.com将会跳转到https://www.baidu.com。在浏览器中抓包后,查看HTTP响应如下:

1
2
3
4
5
6
7
HTTP/1.1 302 Moved Temporarily
Server: bfe/1.0.8.18
Date: Fri, 28 Feb 2020 15:47:24 GMT
Content-Type: text/html
Content-Length: 161
Connection: keep-alive
Location: https://www.baidu.com/

注意到第一行302 Moved Temporarily,说明这是一个临时重定向,重定向的结果不会被浏览器缓存。如果你再次输入http://www.baidu.com并按下回车,你可以通过抓包看到一样的HTTP响应代码。

301永久重定向

301是永久重定向(Moved Permanently),永久意味着重定向的结果会被浏览器缓存。在浏览器中输入地址http://google.com/,抓包后响应头如下:

1
2
3
4
HTTP/1.1 301 Moved Permanently
Location: http://www.google.com/
Content-Type: text/html; charset=UTF-8
......

当第二次访问http://google.com/的时候,在浏览器控制台查看请求,可以看到的状态码后面有一句“from disk cache”,说明请求实际上没有发送出,重定向被浏览器缓存下来了。
HTTP 301重定向

303、307和308重定向

经过前面的测试,我们知道:

  • 301是永久重定向,重定向结果会被浏览器缓存;
  • 302是临时重定向,重定向结果不会被缓存。

不过,如果查看HTTP状态码列表,就会发现,除了301和302,重定向代码还有303、307和308:

  • 303 See Other
  • 307 Temporary Redirect
  • 308 Permanent Redirect

实际上,301和302重定向代码在HTTP 1.0版本就已经出现。

在HTTP 1.0规范中,要求浏览器在重定向时保持请求方法和请求主体不变。即如果一个POST请求发到服务器,服务器返回了301或302重定向代码,浏览器应当使用POST方法像新地址发起请求。

而部分浏览器却不按规范,发生重定向时,将POST方法改为GET方法来发起新的请求。

为了解决这个问题,在HTTP 1.1规范(RFC7231RFC7238)中,新增了303、307和308重定向代码。

根据新的规范:
303为临时重定向代码,在请求新的地址时,必须使用GET方法,且重定向结果不能缓存;
307为临时重定向代码,在请求新的地址时,应该保持原来的请求方法,且重定向结果不能缓存;
308为永久重定向代码,在请求新的地址时,应该保持原来的请求方法,重定向结果可以缓存。

总结

状态码 HTTP版本 是否缓存 请求方法
301 HTTP 1.0 可能改变
302 HTTP 1.0 × 可能改变
303 HTTP 1.1 × 必须是GET
307 HTTP 1.1 × 保持原来的请求方法
308 HTTP 1.1 保持原来的请求方法