Skip to content

HTTP 重定向

http 重定向

重定向是用户代理向某个 URL 发送请求后,服务器会提供一个新的 URL 让用户请求的技术。出现该技术有两个原因:

  • 由于网站可能会重构,比如将一些分类错误的页面移动到新的 URL,为了不出现 404 的沮丧情况,可以使用永久重定向将用户指引到新的页面
  • 由于站点停机或者维护,临时将用户重定向到其他 URL

重定向操作由服务器向请求方发送特殊的重定向响应而触发。重定向响应包含以 3 开头的状态码,以及 Location 标头,该标头保存着重定向的 URL,浏览器在接收到重定向时,它们会立刻加载 Location 标头中提供的新 URL。除了额外的往返操作中会有一小部分性能损失之外,重定向操作对于用户来说是不可见的。

永久重定向

永久重定向的状态码是 301,表示原有的 URL 不可以再使用了,以后应当只访问新的 URL,为此 RSS 阅读器或者搜索引擎爬虫都会更新资源的原始 URL

浏览器接收到 301 响应后,如果最开始发送的是一个 get 请求,那么将会向新的 URL 再次发送 get 请求,但如果之前发送的是例如 post 这样的请求,有可能会转化成 get 请求重新发送,这是浏览器自己的锅,无可奈何

307 响应就是为了解决这个问题,他同样是针对永久重定向,但是转发的请求方法和主体都会与前一次保持相同,详细可见 MDN 文档

临时重定向

临时重定向的状态码是 302,表示资源在当前 URL 不可以访问,但是可以从其他的 URL 获取,为此爬虫不会更新资源的原始链接,和永久重定向一样,他也有更改前一次方法的臭毛病,这里不多做介绍(我暂时还没遇到)

特殊重定向

特殊重定向有两种

一种状态码是 304,表示可以从浏览器缓存中获取资源(有可能会过期)

另一种是 300,表示提供一些重定向的 URL 链接,让用户自己使用

其中前者是最为常用的,比如我们在使用 vite 进行前端开发的时候,经常能看到 304 的请求,这就是 vite 通过借用浏览器的能力加速获取资源。还有 304 状态码还和协商缓存有关

HTML 重定向

如果 http 没有发送相应的状态码,同时想要进行重定向,那么可以通过在 HTML head 处添加一个特殊的 meta 标签

HTML
<head>
  <meta http-equiv="Refresh" content="0; URL=http://example.com/" />
</head>

浏览器检测到该标签后会自动进行跳转,但是不推荐使用,因为倘若服务器发送了重定向的响应,同时文档中有重定向标签,并且二者目标 URL 不一致,就会导致可怕的事情发生(具体是什么我也不知道……)

同时这种重定向也有局限性,即他只能针对 HTML 页面进行重定向,对图片等资源无能为力

JavaScript 重定向

这个更简单了,就是通过使用 window.location = "https://example.com/"; 这样的语句进行重定向

TIP

由于存在上述三种 URL 重定向机制,故规定了一个优先级

  1. HTTP 协议的重定向机制永远最先触发
  2. HTML 的重定向机制会在没有任何 HTTP 协议重定向的情况下触发。
  3. JavaScript 的重定向机制总是作为最后诉诸的手段,并且只有在客户端开启了 JavaScript 的情况下才起作用。

重定向死锁

当后续的重定向路径重复之前的路径的时候,重定向循环就产生了。大多数情况下,这属于服务器端错误。如果服务器检测不到,就会返回 500 Internal Server Error。如果只有一台服务器,这个问题应该是可以在服务端检测到的,但是如果有多台服务器,对于每一台服务器来说,都无法获得一个全景图,因此很难解决