通过“超链接”从一个“超文本”跳转到另一个“超文本”是万维网的一个关键特性。正是通过这一特性,使得分散在世界各地的文档连接在一起,形成了复杂的网状结构,用户可以在浏览时随意点击链接跳转页面,再加上浏览器提供的前进、后退、书签等辅助功能,让用户在文档间跳转时更加方便,有了更多的主动性。

我们把用户主动发起的跳转称之为“主动跳转”,而用户无法控制的跳转则被称之为“被动跳转”,HTTP协议中有个专有名词“重定向”,就是形容“被动跳转”的。

重定向的过程

状态码3XX跟重定向有莫大的关系,301是“永久重定向”,302是“临时重定向”,浏览器收到这两个状态码就会跳转到新的URI。

那么,浏览器具体是怎么实现重定向的呢?
image.png
当我们请求一个重定向的地址,它会返回状态码为302,然后浏览器会根据重定向地址再次请求正确的页面,也就是说一次请求浏览器最终发送了两次HTTP。请求第一个请求返回了 302,然后第二个请求就被重定向到了“/index.html”。但如果不用开发者工具的话,你是完全看不到这个跳转过程的,也就是说,重定向是“用户无感知”的。

我们可以看一下第一次请求的响应报文
image.png
这里的头字段Localtion就是标识的服务器要求重定向的URI。

浏览器收到 301/302 报文,会检查响应头里有没有“Location”。如果有,就从字段值里提取出 URI,发出新的 HTTP 请求,相当于自动替我们点击了这个链接。

没有Localtion字段会怎样

当我们的301、302状态码没有返回Localtion字段时,浏览器无法帮我们跳转,页面显示为下图
image.png

重定向状态码

重定向最常用到的状态码是301和302,还有些不常用的如303、307、308等,效果都差不多。

301 俗称“永久重定向”(Moved Permanently),意思是原 URI 已经“永久”性地不存在了,今后的所有请求都必须改用新的 URI。

302 俗称“临时重定向”(“Moved Temporarily”),意思是原 URI 处于“临时维护”状态,新的 URI 是起“顶包”作用的“临时工”。

浏览器或者爬虫看到 302,会认为原来的 URI 仍然有效,但暂时不可用,所以只会执行简单的跳转页面,不记录新的 URI,也不会有其他的多余动作,下次访问还是用原 URI。301/302 是最常用的重定向状态码,在 3××里剩下的几个还有:

  • 303 See Other:类似 302,但要求重定向后的请求改为 GET 方法,访问一个结果页面,避免 POST/PUT 重复操作;
  • 307 Temporary Redirect:类似 302,但重定向后请求里的方法和实体不允许变动,含义比 302 更明确;
  • 308 Permanent Redirect:类似 307,不允许重定向后的请求变动,但它是 301“永久重定向”的含义。

不过这三个状态码的接受程度较低,有的浏览器和服务器可能不支持,开发时应当慎重,测试确认浏览器的实际效果后才能使用。

重定向的应用场景

首先需要明确的是什么时候需要重定向,一个最常见的原因就是“资源不可用”,需要用另一个新的 URI 来代替。

至于不可用的原因那就很多了。例如域名变更、服务器变更、网站改版、系统维护,这些都会导致原 URI 指向的资源无法访问,为了避免出现 404,就需要用重定向跳转到新的 URI,继续为网民提供服务。

另一个原因就是“避免重复”,让多个网址都跳转到一个 URI,增加访问入口的同时还不会增加额外的工作量。

例如,有的网站都会申请多个名称类似的域名,然后把它们再重定向到主站上。像是bing就是这样的。

知道了什么时候使用,接下来就要考虑使用“永久”还是“临时”了。

301 的含义是“永久”的。

如果域名、服务器、网站架构发生了大幅度的改变,比如启用了新域名、服务器切换到了新机房、网站目录层次重构,这些都算是“永久性”的改变。原来的 URI 已经不能用了,必须用 301“永久重定向”,通知浏览器和搜索引擎更新到新地址,这也是搜索引擎优化(SEO)要考虑的因素之一。

302 的含义是“临时”的。

原来的 URI 在将来的某个时间点还会恢复正常,常见的应用场景就是系统维护,把网站重定向到一个通知页面,告诉用户过一会儿再来访问。另一种用法就是“服务降级”,比如在双十一促销的时候,把订单查询、领积分等不重要的功能入口暂时关闭,保证核心服务能够正常运行。

重定向的相关问题

重定向最需要注意的两个问题:

  1. 性能损耗

一次请求变成两次请求,虽然301、302报文很小,但是大量的请求对服务器的影响也是不可忽视的。站内重定向还好,可以长连接复用,站外重定向就要开两个连接,如果网络连接质量差,那成本可就高多了,会严重影响用户的体验。

  1. 循环跳转

如果重定向的策略设置欠考虑,可能会出现“A=>B=>C=>A”的无限循环,不停地在这个链路里转圈圈,后果可想而知。

小结

  1. 重定向是服务器发起的跳转,要求客户端改用新的 URI 重新发送请求,通常会自动进行,用户是无感知的;
  2. 301/302 是最常用的重定向状态码,分别是“永久重定向”和“临时重定向”;
  3. 响应头字段 Location 指示了要跳转的 URI,可以用绝对或相对的形式;
  4. 重定向可以把一个 URI 指向另一个 URI,也可以把多个 URI 指向同一个 URI,用途很多;
  5. 使用重定向时需要当心性能损耗,还要避免出现循环跳转。