file://协议下XMLHttpRequest和fetch会直接失败,因浏览器将file://视为null源并禁止CORS请求;localStorage数据不共享,sessionStorage几乎完全禁用;Service Worker和WebAssembly加载必然失败;可靠测试应使用本地HTTP服务。

file:// 协议下 XMLHttpRequest 会直接失败
双击打开 HTML 文件时,浏览器使用 file:// 协议加载页面,此时绝大多数现代浏览器(Chrome、Edge、Firefox)会禁止 XMLHttpRequest 和 fetch() 发起跨源请求——哪怕目标是本地 JSON 文件,也会触发 net::ERR_FAILED 或 Access to fetch at 'file:///...' from origin 'null' has been blocked 错误。
这是因为 file:// 的 origin 被视为 null,而 CORS 规范明确禁止 null 源发起非简单请求;即使只是读取同目录下的 data.json,也属于被拦截范围。
- Chrome 94+ 默认禁用
file://下的fetch读取本地文件(包括相对路径) - Firefox 对
XMLHttpRequest的限制更早,且不提供绕过开关 - 仅少数旧版浏览器(如 IE11)或 Electron 环境下才可能“看似正常”,但这不是标准行为
localStorage 和 sessionStorage 在 file:// 下表现不一致
localStorage 在 file:// 协议下多数浏览器仍可写入,但每次双击打开都是新 origin(null),导致数据不共享:前一次保存的值,下次双击就查不到。
sessionStorage 更严格,几乎在所有主流浏览器中对 file:// 完全禁用,调用 sessionStorage.setItem 会静默失败或抛出 SecurityError。
立即学习“前端免费学习笔记(深入)”;
- Chrome 会允许
localStorage写入,但每个file://页面被视为独立域,无法复用 - Safari 直接拒绝
localStorage访问,报QuotaExceededError - 不要依赖
file://测试登录态、缓存逻辑或任何需持久化/会话保持的功能
Service Worker 和 WebAssembly 加载必然失败
Service Worker 注册必须在 HTTPS 或 localhost 下进行,file:// 协议下调用 navigator.serviceWorker.register 会立即返回 DOMException: Failed to register a ServiceWorker。
WebAssembly 模块(.wasm)若通过 fetch() 加载,同样受 file:// 网络限制;即使改用 WebAssembly.instantiateStreaming,底层仍依赖 fetch,无法绕过。
- 常见错误信息:
Uncaught DOMException: Failed to register a ServiceWorker for scope - WASM 文件若用
fetch('lib.wasm')加载,会卡在 pending 或直接 reject - 临时解法只能是改用
WebAssembly.instantiate+ArrayBuffer预加载,但代码复杂度陡增,且不适用于大模块
快速验证是否真能“双击测试”:检查控制台报错和 network 面板
别只看页面渲染是否正常——很多功能表面跑通,实际关键链路已中断。打开开发者工具后重点看两处:
- Console 标签页:搜索
blocked、SecurityError、Failed to register、net::ERR_ - Network 标签页:过滤 XHR/fetch 请求,看状态是否为
(blocked)或failed,响应为空或显示file://不支持 - 右键检查元素 → 查看
Application面板 → Storage:确认localStorage是否真有数据,且刷新后是否还在
真正可靠的本地测试方式,始终是起一个最小 HTTP 服务:python3 -m http.server 8000 或 npx serve -s,让页面运行在 http://localhost:8000 下——协议一换,大部分限制自动解除。



















