HTTP 重定向
基本含义
在 HTTP 请求服务中,服务器可以通过返回一个状态码为 3xx 的重定向响应来告知调用方(通常是浏览器)当前访问的链接需要进行重定向访问,响应头中会带有一个Location 字段,注明重定向后的目的地址。浏览器接收到这个重定向响应后,会访问 Location 中指定的链接。
用户对于这个过程通常是没有太明显的感知的,一切都是在客户端和服务端之间完成,用户最直接的感知就是页面响应的时间可能稍微增加。不过如果在重定向过程中出现其他异常,例如重定向的请求不存在或者网络超时等,用户还是能够明显感受到页面加载缓存的。
重定向相关的状态都是 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.com 和 baidu.com 都能访问到百度的页面。
3、强制跳转 HTTPS
当页面支持 HTTPS 时,如果用户通过 HTTP 协议进行访问,那么服务端通常会强制指定重定向跳转进行 HTTPS 访问。需要注意的是,POST 请求经过 301 和 302 重定向后,会重新以 GET 方法进行请求,此时表单内的请求参数会丢失,可能会导致请求失败,这在服务器开发过程中尤其需要注意。
4、避免页面重复提交
对于像编辑、删除等提交表单的操作,我们需要避免用户通过刷新页面进行重复提交,因此可以将其重定向到临时的进度展示页,比如 303。对于响应时间较长的页面请求也可以这么处理。这样,用户能够感知到操作已经在执行,即便进行刷新或者重新访问,也不会重复触发提交的操作。
|