本文要点
HTTP重定向排在第一位,原因不在它“更快”,而在于它发生的阶段不同
meta refresh排在第二位,它的生效前提是这次请求没有收到HTTP重定向响应
JavaScript跳转排在最后,它的生效条件比前两种多一层

本文目录
先给结论:三种机制不是同时生效,而是排队触发
如果你在一个练习页里同时写了HTTP重定向、meta refresh和JavaScript跳转,想知道哪个先起作用,答案是有固定顺序的:HTTP重定向最先触发,meta refresh在没有HTTP重定向时才触发,JavaScript跳转排在最后,并且只在客户端开启JavaScript时起作用。
依据是MDN的重定向文档。文档在“优先级”一节写得很直接:HTTP协议的重定向机制永远最先触发,因为它们甚至在没有传输页面的情况下就已经存在;HTML的重定向机制(meta)会在没有任何HTTP协议重定向的情况下触发;JavaScript的重定向机制总是作为最后诉诸的手段,并且只有在客户端开启了JavaScript的情况下才起作用。
这句话可以拆成两层理解。第一层是触发条件:HTTP重定向不需要页面到达浏览器就能生效,所以它天然排在前面。第二层是依赖关系:meta refresh和JavaScript都写在页面里,页面必须先被传输到浏览器,它们才有机会执行。
所以判断顺序可以这样定:先看这次请求有没有收到3开头的状态码和Location标头;没有,再看页面里有没有meta refresh;再没有,才轮到JavaScript。下面所有页面和地址都是练习用的自建示例,不是对某个真实站点的记录。
适用范围:本文只讲这三种重定向机制的触发顺序和各自生效条件,不讲服务器配置怎么写,也不涉及茶类内容。
HTTP重定向为什么排第一:它在页面到达之前就已经发生
HTTP重定向排在第一位,原因不在它“更快”,而在于它发生的阶段不同。
按MDN文档的说明,重定向操作由服务器向请求发送特殊的重定向响应而触发,这个响应包含以3开头的状态码,以及保存着重定向URL的Location标头。浏览器接收到重定向时,会立刻加载Location标头中提供的新URL。
关键点在这里:浏览器拿到的是重定向响应,而不是页面内容。也就是说,页面本身还没有被传输,页面里的meta refresh和JavaScript代码都还没有机会被解析和执行。所以只要服务器返回了重定向响应,页面里写什么都不影响这次跳转。
一个自建情境(示例,不是对某个真实站点的记录):你在练习目录里放一个页面 exercise/start.html,里面同时写了meta refresh和JavaScript跳转。如果服务器对这个地址返回了带Location的重定向响应,浏览器会直接去Location指向的地址,start.html里的两段跳转代码都不会执行。
这里要分清一件事:HTTP重定向的触发不依赖页面内容,所以它和另外两种机制不在同一个层面上竞争。它不是“先执行”,而是“另外两种还没轮到”。
meta refresh的生效条件:没有HTTP重定向,且页面是HTML
meta refresh排在第二位,它的生效前提是这次请求没有收到HTTP重定向响应。
按MDN文档的说明,HTML重定向机制是在页面的head里添加一个meta元素,把http-equiv属性的值设置为refresh。当显示页面的时候,浏览器会检测该元素,然后跳转到指定的页面。content属性的值开头是一个数字,指示浏览器在等待该数字表示的秒数之后再进行跳转。
这句话给出了两个生效条件。第一,页面必须被显示,浏览器才会检测这个元素,所以它依赖页面已经传输到浏览器。第二,它只适用于HTML页面或类似的页面,文档明确说这种方法不能应用于图片或者其他类型的内容。
content开头的秒数决定了等待时间。文档建议始终将其设置为0,以获得更好的无障碍体验。这一点值得单独记:写0不是随便选的,而是文档给出的建议值。
一个自建示例(练习数据,不是真实站点):在练习目录里新建 exercise/meta-demo.html,head里写一个meta元素,http-equiv设为refresh,content设为0,URL指向exercise/next.html。用浏览器打开meta-demo.html,观察它是否跳到next.html。这个示例只用于观察meta refresh的行为,不涉及任何真实网址。
JavaScript跳转的生效条件:客户端开启JavaScript,且代码被执行到
JavaScript跳转排在最后,它的生效条件比前两种多一层。
按MDN文档的说明,JavaScript中重定向机制的原理是设置window.location的属性值,然后加载新的页面。文档同时指出,这种方式并不适用于所有类型的资源,并且只有在执行JavaScript的客户端上才能使用。
这句话里有两个限制。第一是资源类型:和meta refresh一样,它依赖页面被加载,不能用于图片这类非页面资源。第二是执行环境:客户端必须开启JavaScript,代码必须被执行到。
文档还提到,JavaScript跳转相比前两种提供了更多可能性,比如只有在满足特定条件的情况下才可以触发重定向。这一点决定了它的定位:它不是默认的跳转手段,而是需要条件判断时才用的手段。
一个自建示例(练习数据,不是真实站点):在练习目录里新建 exercise/js-demo.html,在script里写一行把window.location设为exercise/next.html。用浏览器打开,观察跳转是否发生。如果你想验证“关闭JavaScript后不生效”,可以在浏览器设置里临时关闭JavaScript再打开同一页面,观察它是否还跳。这一步只改浏览器设置,不改任何系统文件,操作前建议记下原来的设置以便恢复。
三种机制同时写在一个页面里,实际会发生什么
把三种机制放在同一个练习页里,可以按下面的顺序推演结果。
第一步,看服务器返回什么。如果返回的是带Location的3开头响应,浏览器直接去新地址,页面里的meta和JavaScript都不会执行。这是HTTP重定向优先的直接体现。
第二步,如果没有HTTP重定向,页面被传输到浏览器。浏览器解析head时检测到meta refresh,按content里的秒数等待后跳转。这时JavaScript可能还没执行到,也可能已经执行,取决于页面结构和加载顺序。
第三步,如果meta refresh不存在,或者因为某种原因没有生效,JavaScript跳转才作为最后手段起作用。
一个自建对照示例(练习数据,不是真实站点):在练习目录里准备三个页面。page-a.html只写meta refresh;page-b.html只写JavaScript跳转;page-c.html两种都写。分别用浏览器打开,记录每个页面最终跳到了哪里。这个对照只用于观察触发顺序,不是对任何真实站点的测试记录。
文档在这里给了一条明确的建议:如果可能,请采用HTTP协议的重定向机制,而不要使用meta元素重定向。原因是假如开发人员修改了HTTP重定向,而忘记修改HTML页面的重定向,二者就会不一致,最终结果或者出现无限循环,或者导致其他问题。
这条建议值得单独记:它说的不是“meta不好用”,而是“两处都写容易改漏一处”。
排查跳转没生效时,按这个顺序逐项检查
如果你的练习页没有按预期跳转,可以按触发顺序反过来查。
第一项,查这次请求有没有收到重定向响应。在浏览器开发者工具的Network面板里看这条请求的状态码是不是3开头,响应头里有没有Location。如果有,页面里的跳转代码本来就不会执行,问题不在页面。
第二项,查meta refresh的写法。看meta元素是不是在head里,http-equiv的值是不是refresh,content里有没有URL。文档只说明了这个元素的用法,没有给出容错规则,所以写法不对时本文不推断浏览器会怎么处理。
第三项,查JavaScript是否执行。确认浏览器没有关闭JavaScript,确认那段设置window.location的代码确实被执行到。如果代码放在条件判断里,条件不成立时跳转不会发生,这是文档提到的“满足特定条件才触发”的用法。
第四项,查是不是形成了循环。文档说明,当后续的重定向路径重复之前的路径时,重定向循环就产生,不会有一个最终的页面返回。如果服务器检测不到,就会返回500 Internal Server Error。有时候服务器端无法检测,比如循环发生在多台服务器之间,这时浏览器会负责检测并返回错误信息。Firefox的提示是检测到该服务器正在将指向此网址的请求无限循环重定向,Chrome的提示是该网页将你重定向的次数过多。
一个自建示例(练习数据,不是真实站点):在练习目录里让page-x.html的meta refresh指向page-y.html,page-y.html的meta refresh又指回page-x.html。打开page-x.html,观察浏览器是否给出循环提示。这个示例只用于观察循环现象,不涉及任何真实站点。
使用限制:这套顺序能回答什么,不能回答什么
这套触发顺序能回答的是:三种机制同时存在时,哪一个先起作用,以及每一种各自需要什么条件。
它不能回答的是:服务器该怎么配置重定向。本文没有涉及服务器配置写法,也没有给出任何配置示例。
文档还给了一条使用上的提醒:应尽可能限制重定向的使用数量,因为每一次重定向都会带来性能上的开销。文档还提到,即便是这项技术可以同样应用于内部链接,也应该尽量避免内部重定向映射,如果能通过修复链接来避免,就应该修复。
另一个限制是适用范围。meta refresh只适用于HTML页面或类似页面,JavaScript跳转也不适用于所有类型的资源。所以这两种机制不能用来重定向图片这类内容。
最后一条边界:本文所有页面名、路径和跳转目标都是练习用的自建示例,不是对任何真实站点的记录,也没有声称做过实测。文档没有给出的浏览器行为细节,本文一律省略,不补推测。
观看知识要点视频 18 秒
18秒无旁白要点导览,文字来自已审核正文;完整步骤、条件及参考资料见下方。
参考资料
以下原始资料提供本文依据;请结合日期、适用条件和产品说明查阅。
请结合原始资料的适用条件阅读。
返回浏览器工具 →