file://协议下fetch被浏览器安全策略禁止,必须用http://localhost启动服务才能正常使用;Python、Node.js或VS Code Live Server均可快速启动本地服务器。

file:// 协议下 fetch 会直接报 net::ERR_FAILED
双击打开 index.html 时,浏览器用的是 file:// 协议,此时几乎所有现代浏览器(Chrome、Edge 主力)都会拦截 fetch('./data.json') 或 XMLHttpRequest 对本地文件的请求。错误信息通常是:net::ERR_FAILED 或 Access to script at 'file:///' from origin 'null' has been blocked。这不是路径写错了,是协议层禁止——哪怕 JSON 文件真在同目录下,也读不到。
Firefox 略宽松,但依然不支持 fetch 读取同目录 JSON;localStorage 虽能用,但每次双击新开窗口会被视为不同源,导致数据不共享。
- 适用场景:纯静态页面(仅 HTML + CSS + 内联 JS,无任何网络请求、无模块导入、无 Service Worker)
- 图片/CSS/内联脚本可正常加载,但所有路径必须用相对路径(如
./style.css),不能写file:///xxx - 根本问题不是“代码有问题”,而是浏览器安全模型不允许
file://发起资源获取类操作
http://localhost 启动后 fetch 才真正可用
只要项目里有 fetch、import、localStorage 持久化、或要用 history.pushState 做前端路由,就必须走 http://localhost。这不是“更专业”,而是 API 的硬性要求。
最轻量的启动方式:
立即学习“前端免费学习笔记(深入)”;
- Python 用户:
python -m http.server 8000(Python 3 自带,无需安装) - Node.js 用户:
npx http-server -c-1(-c-1禁用缓存,适合开发) - VS Code 用户:装
Live Server插件,右键 HTML → “Open with Live Server”
注意端口别选 80/443(需管理员权限),也避开 3000、8080 这类常被占的端口。启动后访问 http://localhost:8000/index.html,一切就和线上环境一致了。
CDN 引入失败时,file:// 下连 onerror 都不触发
<script src="https://cdn.jsdelivr.net/npm/vue@3.4.21/dist/vue.global.js" onerror="this.src='js/vue.global.js'"></script> 这种降级写法,在 file:// 下根本不会执行 onerror——因为 Chrome/Edge 直接阻止所有外部 script 加载,连请求都不发,自然没错误事件可捕获。
要验证 CDN 降级是否生效,必须用 http://localhost 启动,再手动断网或改错 CDN 地址测试。
- 本地引入报
net::ERR_FILE_NOT_FOUND,90% 是路径算错了:./js/vue.js是相对于 HTML 文件位置,不是项目根目录 - 推荐统一用根相对路径:
/js/vue.js,但前提是已启动 HTTP 服务且服务器能正确映射 - 最靠谱的排查方式:开开发者工具 Network 面板,看浏览器实际发出的请求 URL 是什么
GitHub Pages 和 raw.githack 不是“替代双击”的方案
它们解决的是“让别人也能访问”,不是“绕过本地限制”。比如你把 index.html 和 data.json 一起传到 GitHub,用 raw.githack 生成链接:https://raw.githack.com/user/repo/main/index.html,页面能打开,但里面的 fetch('data.json') 依然会跨域失败——因为 raw.githack 返回的响应头没带 Access-Control-Allow-Origin。
真正能跑通完整逻辑的在线托管方式只有:
- GitHub Pages(启用后地址为
https://user.github.io/repo/,自动带 CORS) - 自己搭的 Vercel / Netlify(静态部署,自动处理 MIME 和 CORS)
CodePen、StackBlitz 这类在线编辑器本质是沙盒,它们把你的 HTML/CSS/JS 拼成一个新页面再运行,不加载你本地的 JSON 或 JS 文件,也不代表真实部署行为。
最容易被忽略的一点:能双击打开 ≠ 代码可部署。很多人在本地调通了,上线后才发现 fetch 报 CORS,或者路径全错——那只是因为一直没在真实 HTTP 环境里测过。



















