← 中文资源

简体中文版本

SecurityError — pushState 不可用于跨源 URL

通过保持 history URL 同源、仅传路径/查询/哈希而非完整外部 URL,修复 pushState 的 SecurityError。

阅读英文原文

症状

遇到“SecurityError — pushState 不可用于跨源 URL”时靠猜测只会浪费时间。请按证据排查:先复现症状,再执行针对性诊断,定位根因后修复,并用明确检查验证结果。

可观察到的症状包括:

  • pushState 调用处报同源检查失败
  • pushState 本地可用,置于 CDN 或不同主机后抛错
  • 错误提到的 URL 与文档源不同

诊断

先在隔离环境中复现故障,再按顺序执行以下检查,逐步缩小范围。

步骤 1

console.log(location.origin); console.log(new URL(target, location.href).origin);

源不同即解释 SecurityError;pushState 只接受同源 URL。

步骤 2

git grep -n "pushState\|replaceState"

审查调用可找出哪一处传入了绝对的跨源 URL。

常见诱因(按出现频率排序):

  • pushState 传入的 URL 与文档源不同
  • 相对基准或尾斜杠解析成不同源
  • 应用被嵌入并基于父源构造 URL

根因

history.pushState 与 replaceState 要求目标 URL 与文档同源。否则浏览器抛 SecurityError,以防跨源操纵历史记录。

修复

仅传入同源路径、查询与哈希(如 “/users/1?tab=posts”),相对 URL 基于 location.href 解析,切勿推入外部绝对 URL。

注意:手动重建路径可能在应用部署于子路径时丢弃基础路径;应从 location 推导基础。

// ❌ cross-origin -> SecurityError
// history.pushState({}, '', 'https://evil.example.com/steal');

// ✅ same-origin path only
history.pushState({ page: 1 }, '', '/users/1?tab=posts');

// resolve relative to the current document origin
const next = new URL('/users/2', location.origin).pathname;
history.pushState({ page: 2 }, '', next);

验证

在应用中导航并确认 URL 更新无错误且前进后退可用;断言推入的 URL 与 location.origin 同源。

修复后补充一条回归测试,复现原始症状,防止问题再次出现。

这类故障通常是环境问题而非纯逻辑错误,因此在缺陷记录中应写明完整命令、环境变量与工作目录。请用最小的脚本复现,待最小用例清楚后再扩大范围。为这类故障准备一份简短的排查清单,能显著减少下次排障时间。