搞懂 HTTP 重定向 - 如何优雅地使用 301

发表于 3年以前  | 总阅读数:402 次

最近一段时间,连续遇到了两次跟重定向相关的问题,本着知己知彼百战百胜的态度,我决定深入了解一下,顺便跟大家分享一下。

作为前端开发,大家对重定向一定不陌生,不就是永久重定向和临时重定向嘛,谁还不知道呢 。

那么大家是否知道永久重定向和临时重定向的区别呢?如果不小心设置了永久重定向该如何取消呢?如何优雅地使用重定向呢?接下来就让我们来一探究竟吧。

URL 重定向,能够将多个 URL 指向同一个页面,这一技术有着多种用途。在 HTTP 中有一个专门的响应,叫做 HTTP 重定向,也就是所有 3 开头的响应(这个相信大家都背过)。

除了 HTTP 重定向,还有其他方式能够进行重定向,本文也会介绍。

内容较长,我们先看一下本文的内容架构:

1 . HTTP 重定向详解 2 . 其他类型的重定向方式 3 . 重定向的使用场景 4 . 如何优雅地使用 301

  1. HTTP 重定向

在 HTTP 中,服务器可以通过返回一个重定向响应来进行重定向。这个重定向响应有一个以 3 开头的状态码 ,并且有一个 Location 头字段 表示要重定向到的位置。

浏览器接收到这个重定向之后,会立即加载 Location 中指定的 URL。通常这一过程耗时极端,用户基本注意不到这个过程。

重定向过程如下图所示:

重定向过程

1.1 重定向状态码及含义

前面提到,重定向相关的状态码都是以 3 开头的,主要有以下 9 种状态码:

状态码 状态短语 状态含义
300 Multiple Choices 当请求的 URL 对应有多个资源时(如同一个 HTML 的不同语言的版本),返回这个代码时,可以返回一个可选列表,这样用户可以自行选择。通过 Location 头字段可以自定首选内容。
301 Moved Permanetly 当前请求的资源已被移除时使用,响应的 Location 头字段会提供资源现在的 URL。直接使用 GET 方法发起新情求。
302 Found 与 301 类似,但客户端只应该将 Location 返回的 URL 当做临时资源来使用,将来请求时,还是用老的 URL。直接使用 GET 方法发起新情求。
303 See Other 用于在 PUT 或者 POST 请求之后进行重定向,这样在结果页就不会再次触发重定向了。
304 Not Modified 资源未修改,表示本地缓存仍然可用。
305 Use Proxy 用来表示必须通过一个代理来访问资源,代理的位置有 Location 头字段给出
306 Switch Proxy 在最新版的规范中,306 状态码已经不再被使用。最初是指“后续请求应使用指定的代理”。
307 Temporary Redirect 与 302 类似,但是使用原请求方法发起新情求。
308 Permanent Redirect 与 301 类似,但是使用原请求方法发起新情求。

总共有 9 个与重定向相关的状态码,其中 301/302/304 都比较常见,305/306 使用较少,本文不做介绍(其实我也不懂,也没用过 )。这 9 种状态码可以分成 3 大类,分别是:永久重定向、临时重定向以及特殊重定向。

1.2 永久重定向类

301 和 308 都属于永久重定向。永久重定向意味着原始 URL 不再可用,替换成了一个新的内容。所以搜索引擎、聚合内容阅读器以及其他爬虫识别这两个状态码时,会更新旧 URL 的资源

划重点:这个就是永久重定向和临时重定向的区别。

规范中,301 本来不允许改变请求方法,但是已有的浏览器厂商都使用了 GET 方法进行新的请求。所以创建了 308 用来处理需要使用非 GET 进行重定向的场景。

1.3 临时重定向类

302/303/307 都属于临时重定向。有时,当原有资源因为一些不可预测的原因而临时无法访问时,可以通过临时重定向的方式将请求转移到另一个地方。搜索引擎和爬虫不应该记住这个临时的连接。

此外,临时重定向还可以用来在创建、修改和删除时展示临时的进度页,这里通常使用 303。

302 和 307 的关系类似于 301 和 308,参见上文。

1.4 特殊重定向类

除此之外,300/304/305/306 可以归属到特殊重定向类。这里重点说一下 304,304 是 HTTP 缓存中的一个重要内容,表示资源未修改,相当于将资源重定向到本地缓存。

关于 HTTP 缓存的详细内容,可以查看这篇文章:浏览器缓存策略之扫盲篇

  1. 其他类型的重定向方式

HTTP 是最简易使用的重定向方式,但是有些时候我们并不能够操作服务端。好在,除了 HTTP 重定向外,还有两种方式:通过<meta>进行 HTML 重定向和通过 DOM 的 JS 重定向。

2.1 HTML 重定向

如下代码所示,我们可以通过在<meta>元素上设置http-equiv="Refresh可以实现页面的重定向。

<head>
  <meta http-equiv="Refresh" content="0; URL=https://example.com/">
</head>
复制代码

content属性需要以数字开头,表示多少秒之后重定向到指定页面。通常我们设置为 0。

注意,这一方式只适用于 HTML

2.2 JavaScript 重定向

这个大家都用过,使用window.location可以重定向页面。这个方法很常见,不过多做介绍。

当然,这一方式只在 JavaScript 的客户端执行环境有效。

上述所介绍的三种重定向方式中,按照优先级顺序如下:HTTP > HTML > JavaScript。这和我们所知道的文件的请求处理顺序一致,不过多解释。

  1. 重定向的使用场景

不同类别的重定向有不同的使用场景,大致可以分为以下几类:

  • 网站别名:通常情况下,对于一个资源,我们只有一个 URL,但有些特殊情况下,资源会存在多个 URL,这个时候就需要用到重定向。

  • 提高网站的可达率:比如 www.example.comexample.com都可以访问到指定网站。

  • 迁移到新的站点:因为某些原因旧站点被废弃,但仍然希望之前已经存在的连接和收藏书签能够生效,这是可以使用重定向。

  • 强制跳转 HTTPS:当我们的网站支持 HTTPS 时,通常会强制使用 HTTPS,所以访问 HTTP 时需要做重定向跳转。

  • 保证已有链接可用:站点的维护是一个长时间的过程,有时,我们在进行重构时,会对一些链接或路由进行调整,这时候我们内部的 URL 可以修改,但是对于已在被外部引用了的链接却无法修改。为了保证这部分的链接可用,我们通常需要设置重定向。

  • 对于危险操作进行重定向:类似编辑删除等危险操作,为了避免用户刷新时重复触发危险操作,我们可以将其重定向到临时的进度展示页,比如使用 303。对于耗时较长的请求也可以这么处理。

  1. 如何优雅地使用 301

有些时候,我们对于永久重定向的理解并不够,在仓促之中使用了 301 永久重定向时就会遇到这样的一个坑,那就是不管我们怎么重新设置,(有些)浏览器都仍然使用最开始设置的 301 永久重定向。

这时,我们的用户甚至是我们自己的状态大概是这样的:

网站:忍法 - 永久重定向之术 用户&我们:我是谁?我在哪?我该怎么回去?

往往在错误配置了 301 之后,我们需要面临的问题就是取消最初的 301?

然而,很不幸的是,似乎并没有好的办法能够快速的清除用户端已经使用过的错误 301 重定向。

如果用户足够聪明的话,还可以让用户按照我们的说明进行处理。

所以最好的做法是能够搞懂并优雅地使用 301,这样才能避免这一问题。

下面,我们先来复现问题,然后再解释问题。

4.1 准备:使用 Nginx 配置 301 永久重定向

在 Nginx 中,我们可以创建一个 server 块来指定所有内容都进行重定向:

server {
 listen 80;
 server_name example.com;
 return 301 $scheme://www.example.com$request_uri;
}
复制代码

也可以通过rewrite指令指定目录和页面进行重定向:

rewrite ^/images/(.*)$ https://images.example.com/$1 redirect;
rewrite ^/images/(.*)$ https://images.example.com/$1 permanent;
复制代码

对于其他 web 服务器,可以参考 MDN 或者网上的其他教程进行配置。

比如我准备了下面这样一个 nginx.conf 文件。

server {
  listen 80;
  server_name redirect.example.com;
  root /your-path/web-redirect;

  location /original-page {
    # 下面是两种重定向方式,为了测试使用,启用一个即可
    # 永久重定向
    rewrite ^/original-page http://redirect.example.com/301 permanent;
    # # 临时重定向
    # rewrite ^/original-page http://redirect.example.com/302 redirect;
  }

  location /301 {
    try_files $uri /301.html$is_args$args;
  }

  location /302 {
    try_files $uri /302.html$is_args$args;
  }
}
复制代码

301.html/302.html 自行准备即可,内容自己能区分出来就行。

现在我们假设不小心将初始页面永久重定向到了 301 页面,现在想取消这一行为,临时重定向到 302 页面。

  1. 先开启永久重定向的规则,在浏览器访问http://redirect.example.com/original-page,会发现重定向到了 301。
  2. 关闭永久重定向规则,开启临时重定向,再次访问初始页面,看看是否重定向到了 302 页面。

至此,我们会发现,301 之后,浏览器会记住第一次的 301,忽略之后的其他重定向。那这样到底是为什么呢?

4.2 浏览器会缓存“301”永久重定向

这所以会这样,这是因为浏览器会缓存“301”永久重定向。

经不完全测试,各浏览器的缓存情况如下:

是否缓存 重启是否清除 时间改为 1 年后是否失效 5 年后
Chrome 未清除 未失效 未失效
FireFox 未清除 未失效 未失效
Safari 清除 失效 失效
IE --(没测)-- -- -- --

可以看出除了 Safari 重启/修改时间之后,能够使用新的重定向,Chrome/Firefox 都会无限期的缓存 301 重定向。

在 FireFox 中我们也可以简单验证下,输入about:cache,在磁盘缓存中可以找到相关的缓存项。如下:

FireFox中的301缓存内容

浏览器为什么会缓存 301 重定向呢?其实,HTTP RFC 中规定 301 是一个可缓存的响应,所以浏览器会根据响应中的 HTTP 缓存头进行缓存。如果我们没有提供明确的缓存头,浏览器就会默认永久缓存 301 响应,因为 301 是永久重定向的意思。

这里笔者偷懒没有测试 IE,但是鉴于有浏览器(Chrome/Firefox)会无限期缓存 301 重定向,那么我们就需要试着去解决这一问题 —— 如何清除 301 重定向缓存。

4.3 如何清除 301 重定向缓存

内心戏:不是说没法清除吗?这怎么介绍了。我:别急,先看完。

既然是缓存行为,那么我们就可以通过常规的缓存清理方式来处理,包括但不限于以下几种方式:

  • 控制台禁用缓存
  • 清除历史记录
  • Network 面板清除缓存

这里大家可以自行尝试以下,如果不行的话,记得多试 1-2 遍就行(至于为什么要多试,我也很奇怪,有的时候就是清两遍就好了)。

如果大家验证了上面的几种清除方式,就会发现确实是行之有效的。那为什么我会说没有很好地方式去清除呢?

大家细想,当我们将错误的 301 请求发布到线上环境了,并且影响了数以万计的用户时,我们要怎么通知并教会用户按照我们的方式去清除缓存呢?当然,清除历史记录算是最便捷的方式了,如果真的不行遇到了这种情况,那就通知用户这么清除吧 。

4.4 优雅地使用 301

为了避免上面需要清除的情况,最好的做法是优雅地使用 301。

前面解释浏览器为什么会缓存 301 重定向时,已经隐晦地提到了这一方法。

既然浏览器认为这是一个可以缓存的资源,并且我们可以通过缓存头来控制。那么在使用 301 时,我们将其设置为不缓存就可以了。比如设置 Cache-Control: no-storeCache-Control: no-cache

location /original-page {
+ add_header Cache-Control no-store;
  # 永久重定向
  rewrite ^/original-page http://redirect.example.com/301 permanent;
  # 临时重定向
  # rewrite ^/original-page http://redirect.example.com/302 redirect;
}
复制代码

这样设置之后,如果我们再将重定向切换成 302,会发现浏览器不会缓存 301 了,新的重定向可以立即生效了。

总结

以上就是重定向相关的内容。301 使用需谨慎,一定要设缓存头 。

参考资料

[1]维基百科 - HTTP 状态码: https://zh.wikipedia.org/wiki/HTTP%E7%8A%B6%E6%80%81%E7%A0%81

[2]MDN - Redirections in HTTP: https://developer.mozilla.org/en-US/docs/Web/HTTP/Redirections

[3]浏览器将 HTTP 301 缓存多长时间?: https://qastack.cn/programming/9130422/how-long-do-browsers-cache-http-301s

[4]浏览器对 301 重定向的缓存: https://juejin.cn/post/6844904045614743560

[5]Chromium - Feature Request: I need a way to clear the 301 redirect cache: https://bugs.chromium.org/p/chromium/issues/detail?id=633023&can=1&q=clear%20301%20redirects&colspec=ID%20Pri%20M%20Stars%20ReleaseBlock%20Component%20Status%20Owner%20Summary%20OS%20Modified

本文由哈喽比特于3年以前收录,如有侵权请联系我们。
文章来源:https://mp.weixin.qq.com/s/CrGMPGqsLTgmYNWBXe_yhQ

 相关推荐

刘强东夫妇:“移民美国”传言被驳斥

京东创始人刘强东和其妻子章泽天最近成为了互联网舆论关注的焦点。有关他们“移民美国”和在美国购买豪宅的传言在互联网上广泛传播。然而,京东官方通过微博发言人发布的消息澄清了这些传言,称这些言论纯属虚假信息和蓄意捏造。

发布于:1年以前  |  808次阅读  |  详细内容 »

博主曝三大运营商,将集体采购百万台华为Mate60系列

日前,据博主“@超能数码君老周”爆料,国内三大运营商中国移动、中国电信和中国联通预计将集体采购百万台规模的华为Mate60系列手机。

发布于:1年以前  |  770次阅读  |  详细内容 »

ASML CEO警告:出口管制不是可行做法,不要“逼迫中国大陆创新”

据报道,荷兰半导体设备公司ASML正看到美国对华遏制政策的负面影响。阿斯麦(ASML)CEO彼得·温宁克在一档电视节目中分享了他对中国大陆问题以及该公司面临的出口管制和保护主义的看法。彼得曾在多个场合表达了他对出口管制以及中荷经济关系的担忧。

发布于:1年以前  |  756次阅读  |  详细内容 »

抖音中长视频App青桃更名抖音精选,字节再发力对抗B站

今年早些时候,抖音悄然上线了一款名为“青桃”的 App,Slogan 为“看见你的热爱”,根据应用介绍可知,“青桃”是一个属于年轻人的兴趣知识视频平台,由抖音官方出品的中长视频关联版本,整体风格有些类似B站。

发布于:1年以前  |  648次阅读  |  详细内容 »

威马CDO:中国每百户家庭仅17户有车

日前,威马汽车首席数据官梅松林转发了一份“世界各国地区拥车率排行榜”,同时,他发文表示:中国汽车普及率低于非洲国家尼日利亚,每百户家庭仅17户有车。意大利世界排名第一,每十户中九户有车。

发布于:1年以前  |  589次阅读  |  详细内容 »

研究发现维生素 C 等抗氧化剂会刺激癌症生长和转移

近日,一项新的研究发现,维生素 C 和 E 等抗氧化剂会激活一种机制,刺激癌症肿瘤中新血管的生长,帮助它们生长和扩散。

发布于:1年以前  |  449次阅读  |  详细内容 »

苹果据称正引入3D打印技术,用以生产智能手表的钢质底盘

据媒体援引消息人士报道,苹果公司正在测试使用3D打印技术来生产其智能手表的钢质底盘。消息传出后,3D系统一度大涨超10%,不过截至周三收盘,该股涨幅回落至2%以内。

发布于:1年以前  |  446次阅读  |  详细内容 »

千万级抖音网红秀才账号被封禁

9月2日,坐拥千万粉丝的网红主播“秀才”账号被封禁,在社交媒体平台上引发热议。平台相关负责人表示,“秀才”账号违反平台相关规定,已封禁。据知情人士透露,秀才近期被举报存在违法行为,这可能是他被封禁的部分原因。据悉,“秀才”年龄39岁,是安徽省亳州市蒙城县人,抖音网红,粉丝数量超1200万。他曾被称为“中老年...

发布于:1年以前  |  445次阅读  |  详细内容 »

亚马逊股东起诉公司和贝索斯,称其在购买卫星发射服务时忽视了 SpaceX

9月3日消息,亚马逊的一些股东,包括持有该公司股票的一家养老基金,日前对亚马逊、其创始人贝索斯和其董事会提起诉讼,指控他们在为 Project Kuiper 卫星星座项目购买发射服务时“违反了信义义务”。

发布于:1年以前  |  444次阅读  |  详细内容 »

苹果上线AppsbyApple网站,以推广自家应用程序

据消息,为推广自家应用,苹果现推出了一个名为“Apps by Apple”的网站,展示了苹果为旗下产品(如 iPhone、iPad、Apple Watch、Mac 和 Apple TV)开发的各种应用程序。

发布于:1年以前  |  442次阅读  |  详细内容 »

特斯拉美国降价引发投资者不满:“这是短期麻醉剂”

特斯拉本周在美国大幅下调Model S和X售价,引发了该公司一些最坚定支持者的不满。知名特斯拉多头、未来基金(Future Fund)管理合伙人加里·布莱克发帖称,降价是一种“短期麻醉剂”,会让潜在客户等待进一步降价。

发布于:1年以前  |  441次阅读  |  详细内容 »

光刻机巨头阿斯麦:拿到许可,继续对华出口

据外媒9月2日报道,荷兰半导体设备制造商阿斯麦称,尽管荷兰政府颁布的半导体设备出口管制新规9月正式生效,但该公司已获得在2023年底以前向中国运送受限制芯片制造机器的许可。

发布于:1年以前  |  437次阅读  |  详细内容 »

马斯克与库克首次隔空合作:为苹果提供卫星服务

近日,根据美国证券交易委员会的文件显示,苹果卫星服务提供商 Globalstar 近期向马斯克旗下的 SpaceX 支付 6400 万美元(约 4.65 亿元人民币)。用于在 2023-2025 年期间,发射卫星,进一步扩展苹果 iPhone 系列的 SOS 卫星服务。

发布于:1年以前  |  430次阅读  |  详细内容 »

𝕏(推特)调整隐私政策,可拿用户发布的信息训练 AI 模型

据报道,马斯克旗下社交平台𝕏(推特)日前调整了隐私政策,允许 𝕏 使用用户发布的信息来训练其人工智能(AI)模型。新的隐私政策将于 9 月 29 日生效。新政策规定,𝕏可能会使用所收集到的平台信息和公开可用的信息,来帮助训练 𝕏 的机器学习或人工智能模型。

发布于:1年以前  |  428次阅读  |  详细内容 »

荣耀CEO谈华为手机回归:替老同事们高兴,对行业也是好事

9月2日,荣耀CEO赵明在采访中谈及华为手机回归时表示,替老同事们高兴,觉得手机行业,由于华为的回归,让竞争充满了更多的可能性和更多的魅力,对行业来说也是件好事。

发布于:1年以前  |  423次阅读  |  详细内容 »

AI操控无人机能力超越人类冠军

《自然》30日发表的一篇论文报道了一个名为Swift的人工智能(AI)系统,该系统驾驶无人机的能力可在真实世界中一对一冠军赛里战胜人类对手。

发布于:1年以前  |  423次阅读  |  详细内容 »

AI生成的蘑菇科普书存在可致命错误

近日,非营利组织纽约真菌学会(NYMS)发出警告,表示亚马逊为代表的电商平台上,充斥着各种AI生成的蘑菇觅食科普书籍,其中存在诸多错误。

发布于:1年以前  |  420次阅读  |  详细内容 »

社交媒体平台𝕏计划收集用户生物识别数据与工作教育经历

社交媒体平台𝕏(原推特)新隐私政策提到:“在您同意的情况下,我们可能出于安全、安保和身份识别目的收集和使用您的生物识别信息。”

发布于:1年以前  |  411次阅读  |  详细内容 »

国产扫地机器人热销欧洲,国产割草机器人抢占欧洲草坪

2023年德国柏林消费电子展上,各大企业都带来了最新的理念和产品,而高端化、本土化的中国产品正在不断吸引欧洲等国际市场的目光。

发布于:1年以前  |  406次阅读  |  详细内容 »

罗永浩吐槽iPhone15和14不会有区别,除了序列号变了

罗永浩日前在直播中吐槽苹果即将推出的 iPhone 新品,具体内容为:“以我对我‘子公司’的了解,我认为 iPhone 15 跟 iPhone 14 不会有什么区别的,除了序(列)号变了,这个‘不要脸’的东西,这个‘臭厨子’。

发布于:1年以前  |  398次阅读  |  详细内容 »
 相关文章
Android插件化方案 5年以前  |  237231次阅读
vscode超好用的代码书签插件Bookmarks 2年以前  |  8065次阅读
 目录