18143453325 在线咨询 在线咨询
18143453325 在线咨询
所在位置: 首页 > 营销资讯 > 建站知识 > 彻底搞懂 HTTP 3XX 重定向状态码和浏览器重定向

彻底搞懂 HTTP 3XX 重定向状态码和浏览器重定向

时间:2023-02-09 07:36:01 | 来源:建站知识

时间:2023-02-09 07:36:01 来源:建站知识

最近好好研究了一下 HTTP 的 3XX 状态码,发现这里面涉及到的知识点还挺多的,很多在我们日常开发过程中也会用到,于是就想通过这篇文章来和大家聊一聊它们的含义以及应用场景。

3XX 状态码是关于重定向的,常见的状态码有:301,302,303,304,307 和 308。这些状态码大致可以分为三类,其中包括:

这篇文章主要分析永久重定向和临时重定向相关的状态码,至于其他重定向就不在这里细讲了。

PS: 正文里提到的 3XX 响应只包含永久重定向和临时重定向所对应的 HTTP 状态码,不包括其他重定向。

开始

我们既需要明白服务器发送的各种重定向状态码是什么含义,还需要搞清楚浏览器收到这些重定向状态码之后会怎么做。因此本文会从服务器和浏览器两个部分进行讲解。

服务器

永久重定向

永久重定向,是指用户请求的资源地址已经废弃了,现在需要使用新地址来访问,并通过响应 Header 的 Location 字段将这个新的地址告知给用户。

就好比胡同口有一家我们常去的饭店,但是由于旧城改造这家店搬迁到了另一个地方。有一天我们准备去这家店吃饭,发现门口张贴告示:此店已迁移到 XXX,并附上了详细的新地址。也就是说,之后如果我还想去这家店吃饭,只能去新的地址。

301 Moved Permanently

表示请求资源已经被移动到了由 Location 头部指定的 URI 上,是固定的不会再改变。在用新 URL 发起请求时,对于 GET 请求保持不变,但是对于 POST 请求,尽管标准要求浏览器在收到该响应时不应该修改 HTTP Method 和 Request Body,但是大多数浏览器没有遵守这个标准,会把原本为 POST 的请求重定向到 GET 请求上。

我们拿 Chrome 浏览器测试了一下,结果如下:







从上面的截图中可以看出,浏览器在收到 302 响应之后,从 Location 里面获取到了 /pets 这个新的地址,并发起了新的请求。但是,这个新的请求使用的是 GET 方法而非我们原来的 POST 方法,Request Body 也丢失了。

应用场景:

比如某个应用进行了整站重构,重构之后 URL 发生了改变,这时候可以考虑将老 URL 重定向到新 URL。

308 Permanent Redirect

跟 301 一样,唯一的区别就是浏览器不会改变请求的 HTTP Method 和 Request Body。

我们又继续拿 Chrome 测试了一下,结果如下:







可以看出,使用 308 之后,请求的 Method 和 Request Body 都没有发生改变,还是跟原来一样。

临时重定向

由于某些原因,导致用户请求的资源地址临时不可用,但其他某个地址是可访问的,于是就通过响应 Header 的 Location 字段将这个临时地址告知给用户。

就好比我们去一家饭店吃饭,到门口发现老板张贴告示:家里临时有事,请去附近另一个分店用餐,并附上了分店的详细地址。这样,我们就可以先临时去这家分店用餐,等之后老板回来了,我们又可以在原来这家店继续用餐。

302 Found

在收到 302 响应之后,浏览器会发起新的请求,尽管标准要求浏览器在收到该响应时不应该修改 HTTP Method 和 Request Body,但是大多数浏览器都没有遵守这个标准。大多数浏览器会将 302 请求视为 303 请求,也就是说 302 和 303 几乎是一样的。

应用场景举例:

通常图片资源会放到类似 S3 这样的静态资源服务器,出于对隐私和安全的考虑,我们有时不能直接通过静态资源服务器的 URL 访问到这个图片,而是需要后端通过身份凭证去 S3 签发一个临时地址(这个地址用一次就失效了,下一次需要重新签发),然后我们才能通过这个临时地址访问到真正的图片资源。

对于这个场景,302/303 就非常有用了。比如,前端可以使用一个固定的 URL 来访问图片资源 (<img src="/image/foo.jpg"),这个 URL 由后端提供,后端在生成完临时地址之后,可以直接通过 302/303 重定向到这个新的地址,接下来浏览器会再次发起请求,获取新地址指向的这个图片资源。

303 See Other

浏览器在收到 303 响应之后,除 GET 方法保持不变之外,其他所有方法都会被改为 GET 方法,同时 Request Body 也会丢失。一般用于将 POST 方法重定向到 GET 方法。

应用场景举例:

假设我们有一个非常原始的表单,这个表单是通过在 HTML 上设置 action 和 method 来提交的。在表单提交之后,浏览器会自动跳转到 action 所在的地址,并使用 method 所指定的方法向服务器发起请求,在收到服务器的303 响应之后,又需要跳转回原来这个页面。

<form action="http://example.com/api/form" method="POST"> <input type="text" name="name" placeholder="name"> <input type="email" name="email" placeholder="email"> <input type="submit" value="Submit"></form>这里就会出现一个问题,假设我们页面的 URL 是 http://example.com ,我们只能通过 GET 方法请求这个页面。而提交表单所使用的 URL 是 http://example.com/api/form ,我们只能通过 POST 方法来调用这个接口。在使用 POST 方法提交表单之后,如果我们想返回原来的页面,只能使用 GET 方法发起请求,因此我们需要使用 303 状态码,将原来的 POST 方法改成 GET。

307 Temporary Redirect

307 和 303 一样,唯一的区别就是浏览器不会改变请求的 HTTP Method 和 Request Body。对于 POST/PUT 等非 GET 请求很有用。

应用场景:

在上传文件时,我们通常会调用后端提供的某个 API (/upload),但由于上传会占用大量的服务器资源和带宽,这个 API 一般不会处理真正的上传,而是通过另一个专门的上传服务来完成。这意味着我们需要调用两次 API 才能完成上传功能,一次是调用后端接口获取真正的上传地址,另一次是携带 Request Body 请求这个上传地址,完成真正的上传。

如果让两个 API 的请求参数和方法保持一致,那么对于前端来说,只需要发起一次请求即可,后端在生成完上传地址后,通过 307 重定向到这个地址,然后浏览器会使用之前的 Request Body 和 HTTP Method 请求这个新的地址,这样就完成了上传。

注意,如果使用 302 会导致上传失败,原因是 302 会将 PUT 改为 GET 请求,同时 Request Body 也会丢失。

其他常见的重定向场景

域名别称

  1. 扩大站点的用户覆盖面。比如访问 http://www.google.com 会被重定向到 http://google.com
  2. 迁移到另一个域名。
  3. 强制使用 HTTPS 协议。比如访问 http://baidu.com 会被重定向到 https://baidu.com

保持链接有效

当重构网站时,可能会让资源的 URL 发生改变。但我们并不想因此使旧链接失效,因为这些链接不仅可以给你带来宝贵的用户,还能够帮助优化 SEO,因此需要建立从旧链接到新链接的重定向映射。

浏览器

我们已经了解了各种关于重定向的 HTTP 状态码,那么浏览器收到这些状态码之后会做些什么呢?当浏览器收到 3XX 响应之后,是否会将地址栏的 URL 修改为响应 Header 中 Location 字段所指定的 URL,并跳转到这个新的 URL 呢? 请接着往下看。

收到 3XX 响应后,浏览器是否会改变地址栏并跳转?

浏览器是否会改变地址栏并跳转, 其实取决于请求的 URL 是否会让文档加载/重新加载。这里所指的文档加载/重新加载,既包括当我们通过浏览器地址栏访问某个 URL、刷新页面所导致的文档加载,也包括我们通过 window.location 让文档用新的 URL 加载。只有在这些情况下,如果我们请求的 URL 返回了 3XX 响应,浏览器才会读取响应 Header 里面的 Location 字段,并将浏览器的地址栏修改为这个字段所指定的 URL,然后跳转到这个 URL。

一般来说文档加载/重新加载都会产生一个 Document 类型的请求,如下所示:




PS: React Router 这样的路由跳转,不会让文档重新加载 ( 因为使用的是 History API )
但是,如果是通过 fetch/XMLHttpRequest 调用所获取到的 3XX 响应,浏览器是不会改变当前地址栏的 URL 并跳转的。试想,我们在访问图片时,经常会得到很多 302 响应,如果浏览器要跳转 URL,岂不是会导致整个浏览器崩溃。

window.location + 3XX 响应

window.location 能够让文档用新的 URL 加载,默认会将新的 URL push 到浏览器 history 的路由堆栈里面,如果你想使用 replace 的方式,可以调用 window.location.replace() 方法:

window.location = "http://www.mozilla.org";function reloadPageWithHash() { var initialPage = window.location.pathname; window.location.replace('http://example.com/#' + initialPage);}应用场景:

在使用 OAuth2 鉴权时(比如微信登录),可以通过 window.location 重定向到自己服务器的授权地址(支持多个平台登录时,可以由后端统一处理),然后服务器会生成一个三方授权点的地址,并通过 302 响应告知给浏览器,浏览器在收到响应之后会跳转到这个三方授权点的 URL(微信登录页),完成授权之后,三方授权页面会通过 window.location 再重定向回我们自己的页面。

通过 window.location 再配合 302 响应,我们可以快速将用户导向三方授权点,不需要加载任何 JS,非常快速方便。







参考:https://developer.mozilla.org/zh-CN/docs/Web/HTTP/Redirections

关键词:状态,浏览,器重

74
73
25
news

版权所有© 亿企邦 1997-2025 保留一切法律许可权利。

为了最佳展示效果,本站不支持IE9及以下版本的浏览器,建议您使用谷歌Chrome浏览器。 点击下载Chrome浏览器
关闭