meta refresh 会触发页面重载或跳转:仅设秒数(如 content="3")时重载当前页;含 url=(如 content="3; url=/login")时才跳转。
http-equiv="refresh" 的行为取决于 content 属性值:如果只写秒数(如 content="3"),是当前页自动重载;如果带 url=(如 content="3; url=/login"),才是跳转。很多人误以为它“总是跳转”,结果在调试时发现页面刷新了却没走新地址,就是漏写了 url= 部分。
跳转目标 URL 是相对路径时,按当前 HTML 文档的 base URL 解析,不是按浏览器地址栏当前 URL。比如页面通过 /app/v2/user?id=123 访问,但 HTML 在 /static/page.html,那么 content="0; url=./home" 会跳到 /static/home,而非 /app/v2/home。
建议统一用绝对路径或协议相对路径避免歧义:
content="0; url=/dashboard"(根路径)content="0; url=https://example.com/login"(完整 URL)content="0; url=../login" 这类易受部署结构影响的写法如果页面同时存在 <meta http-equiv="refresh" content="2; url=/a"> 和 window.location.href = "/b",实际行为取决于执行时机:meta 刷新由浏览器解析 HTML 时注册,JS 跳转若在 DOMContentLoaded 后触发,会覆盖 meta 行为;但如果 JS 执行失败或被阻塞,meta 仍会在计时结束后生效。
立即学习“前端免费学习笔记(深入)”;
常见陷阱:
meta refresh 和路由跳转,导致双跳或白屏meta refresh,但前端 JS 又立即调用 history.pushState,造成历史记录混乱meta refresh 的秒数精度支持差,content="0.1" 可能直接当 0 处理主流搜索引擎(Google、Bing)基本不将 meta refresh 视为合法重定向,尤其 content 值小于 1 秒时,可能被判定为欺骗性跳转,影响收录。W3C 也明确建议:仅在无服务端重定向能力时作为降级方案使用。
替代更稳妥的做法:
302 或 307 状态码 + Location headerwindow.location.replace() 替代 assign(),避免用户点返回时回到跳转页setTimeout(() => { location.replace(...) }, 3000),便于捕获错误或取消真正要用 meta refresh 的场景其实很窄:纯静态页托管、无后端权限、且必须客户端触发跳转——这种情况下,别忘了加 <noscript><meta ...></noscript> 保底。