HTTP 重定向

基本含义

在 HTTP 请求服务中,服务器可以通过返回一个状态码为 3xx 的重定向响应来告知调用方(通常是浏览器)当前访问的链接需要进行重定向访问,响应头中会带有一个Location 字段,注明重定向后的目的地址。浏览器接收到这个重定向响应后,会访问 Location 中指定的链接。

request initiator chain为什么会重定向 http的重定向的意义_状态码

用户对于这个过程通常是没有太明显的感知的,一切都是在客户端和服务端之间完成,用户最直接的感知就是页面响应的时间可能稍微增加。不过如果在重定向过程中出现其他异常,例如重定向的请求不存在或者网络超时等,用户还是能够明显感受到页面加载缓存的。

重定向相关的状态都是 3XX 的形式,常见的主要有一下9种状态码:

状态码

状态描述

含义

300

Multiple Choices

请求的 URL 对应有多个资源,返回 300 的同时还会返回一个可选列表,用户通过头部的 Location 字段可以决定首选内容

301

Moved Permanently

请求的 URL 已经被修改,响应头的 Location 字段提供资源现在的 URL,客户端将使用 GET 方法发起新的请求,并且将这一重定向结果缓存起来

302

Found

接收到 302 响应后,同301,会使用 GET 方法发起新的请求。但客户端只将 Location 返回的 URL 作为临时资源使用,将来请求时还是使用原来 URL 首先发起请求。

303

See Other

在 PUT 或者 POST 请求之后进行重定向,这样在结果页就不会再次触发重定向了。

304

Not Modified

表示资源未修改,本地缓存仍然可用

305

Use Proxy

表示必须通过 Location 提供的代理位置来访问资源

306

Switch Proxy

表示后续请求应该使用指定的代理,但是在最新版的规范中,306 已经不再被使用

307

Temporary Redirect

临时重定向,与 302 类似,但客户端使用原来的方法(如 POST)发起新的请求

308

Permanent Redirect

永久重定向,与 301 类似,但客户端使用原来的方法(如 POST)发起新的请求

永久重定向

从上面整理的表格可以知道,301 和 308 状态码都属于永久重定向。正如字面意思,永久重定向代表原来的 URL 资源已经不可用,替换成一个新的 URL 资源。所以当客户端识别到响应头中带有这两个状态码时,会更新原来请求 URL 资源记录。

301 和 308 的主要区别是,重新发起新请求时,301 会发起 GET 请求,而 308 会使用原来的方法发起新的请求。在规范中,其实 301 本来也是不允许新请求改变其请求方法的,但是由于市面上现有的浏览器厂商都使用了 GET 方法来发起新的请求,所以才创建了 308 这个状态码来处理需要使用非 GET 方法进行重定向的场景。

临时重定向

302、303、307 都属于临时重定向。当原来的 URL 资源因为某些不可预测的因素导致临时无法访问时,可以通过临时重定向将请求转移到另外一个资源。由于重定向的资源是临时的,因此客户端不会将这个临时的资源缓存至本地,在下一次发起请求时依旧会使用原来的资源。

如果在资源访问时,服务方想提供一些临时的展示页,通常可以使用 303 进行临时重定向。

302 与 307 的关系与永久重定向中的 301 与 308 的关系类似,这里就不再赘述。

其他重定向方式

在生产中常用的几种重定向,其作用优先级跟我们访问资源时文件的请求处理顺序基本一致,即

HTTP > HTML > JavaScript

上面提到的重定向方式,都是通过在响应体头部的 Location 字段指定新的 URL 资源实现的,但是这个操作只能是由服务端控制的,属于 HTTP 的协议范畴。在不方便控制服务端的场景下,还可以通过 HTML 的 <meta> 标签进行 HTML 重定向,或者 DOM 实现 JavaScript重定向。

HTML 重定向

在 HTML 文件中,通过 <meta> 标签进行指定:

<head>
	<meta http-equiv="Refresh" content="0; URL=https://domain.com/index_new"/>
</head>

http-equiv="Refresh" 指定启动重定向,content 后面的数字表示执行重定向的等待时间,单位为秒;后面的 URL 则指定重定向的资源链接。

JavaScript 重定向

这个比较常见,通过指定 window.location 即可实现重定向,这里不再展开。

常见的重定向场景

1、保证原有链接可用

由于网站的维护或者链接的调整,服务器内部的 URL 可能出现变更,但为了保证已经被外部引用的链接以及用户收藏的书签依然可用,这里可以使用重定向。

2、提高网站的可达率

有时候用户访问一个 URL 时,不一定能准确记住完整的链接,针对同一个网站的不同别名,分别使其重定向至该网站的指定 URL,能有效提升用户访问的可达率。比如 www.baidu.combaidu.com 都能访问到百度的页面。

3、强制跳转 HTTPS

当页面支持 HTTPS 时,如果用户通过 HTTP 协议进行访问,那么服务端通常会强制指定重定向跳转进行 HTTPS 访问。需要注意的是,POST 请求经过 301 和 302 重定向后,会重新以 GET 方法进行请求,此时表单内的请求参数会丢失,可能会导致请求失败,这在服务器开发过程中尤其需要注意。

4、避免页面重复提交

对于像编辑、删除等提交表单的操作,我们需要避免用户通过刷新页面进行重复提交,因此可以将其重定向到临时的进度展示页,比如 303。对于响应时间较长的页面请求也可以这么处理。这样,用户能够感知到操作已经在执行,即便进行刷新或者重新访问,也不会重复触发提交的操作。