症状
遇到“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 同源。
修复后补充一条回归测试,复现原始症状,防止问题再次出现。
这类故障通常是环境问题而非纯逻辑错误,因此在缺陷记录中应写明完整命令、环境变量与工作目录。请用最小的脚本复现,待最小用例清楚后再扩大范围。为这类故障准备一份简短的排查清单,能显著减少下次排障时间。