为什么本地文件用 fetch 请求 JSON 会报 CORS 错误?

Newb.一茹 阅读 251

我最近在本地开发一个静态页面,想用 fetch('data.json') 加载同目录下的 JSON 文件,结果浏览器控制台报错:「Access to fetch at ‘file:///…/data.json’ from origin ‘null’ has been blocked by CORS policy」。明明是本地文件,又没跨域,怎么会触发 CORS?

我已经试过把文件放到 VS Code 的 Live Server 里跑,这样就能正常加载,但直接双击 HTML 文件打开就不行。是不是因为 file:// 协议的问题?有没有办法在不启动服务器的情况下解决?

我来解答 赞 2 收藏
二维码
手机扫码查看
1 条解答
司徒心虹
这个问题我当年也踩过坑,说实话浏览器这个报错信息确实容易让人误解。你猜对了,就是 file:// 协议搞的鬼。

问题的根源在于浏览器的安全策略。当你直接双击 HTML 文件打开时,地址栏是 file:/// 开头的,这时候页面的 origin 被浏览器定义为字符串 "null"。注意不是空字符串,而是字符串 "null"。当你用 fetch 请求另一个本地文件时,浏览器会认为这是从一个 origin 为 "null" 的源去访问另一个源,即使它们在同一个文件夹里。

Chrome 和其他现代浏览器出于安全考虑,禁止 file:// 协议的页面发起任何 AJAX 或 fetch 请求。这个设计是为了防止恶意网页读取你本地的文件系统,想象一下如果网页能随意读取你电脑上的文件,那得多危险。

Live Server 能跑通是因为它启动了一个本地 HTTP 服务器,你的页面变成了 http://127.0.0.1:5500,请求 JSON 文件时是同源的,自然就没有 CORS 问题了。

如果你非要不用服务器,有几种方案,但都有局限。

方案一,给 Chrome 加启动参数。关闭所有 Chrome 窗口,然后用命令行启动:

# Windows
chrome --allow-file-access-from-files --disable-web-security --user-data-dir=/tmp/chrome_dev

# Mac
open -a "Google Chrome" --args --allow-file-access-from-files --disable-web-security --user-data-dir=/tmp/chrome_dev


这个方法能跑,但我不建议用。首先每次都要手动启动很麻烦,其次这会关闭浏览器的安全策略,你日常上网千万别用这个模式的浏览器。

方案二,把 JSON 数据直接内嵌到 JS 文件里。如果你的数据是静态的,不经常变动,直接写成一个变量:

// data.js
const localData = {
"users": [
{ "id": 1, "name": "张三" },
{ "id": 2, "name": "李四" }
]
};


然后在 HTML 里用 引入,直接用 localData 这个变量就行。简单粗暴,但失去了 JSON 文件的灵活性。

方案三,如果你只是想快速测试,可以用 Python 一行命令起个服务器。前提是你电脑装了 Python:

# Python 3
cd 你的项目目录
python -m http.server 8080

# 然后访问 http://localhost:8080


或者用 Node.js 的 http-server 包,全局安装后直接运行就行。

说到底,本地开发起个服务器是正道。VS Code 的 Live Server 插件也好,Python 的简易服务器也好,都是几秒钟的事。浏览器的安全策略不是来跟你作对的,是真的在保护用户。我之前为了调试一个本地存储的问题折腾了半天,最后发现就是 file:// 协议下 localStorage 的行为和 http:// 也不一样,坑多了去了。

总结一下,没有服务器的情况下完美解决这个问题的方案基本没有,要么接受安全风险改浏览器参数,要么把数据内嵌,要么老老实实起个本地服务器。建议还是用 Live Server 或者其他本地服务器方案,省心。
点赞 2
2026-03-01 15:00