项目部署到服务器上怎么获取本地的json
项目部署到服务器之后,原来本地通过相对路径或绝对路径读取的json文件,必须先改成通过HTTP请求(fetch或axios)访问服务器上的静态资源路径,才能正常获取。这个问题几乎所有前端开发者都会遇到,本地开发环境一切正常,代码一上服务器就报404或跨域错误,根因是运行环境变了:浏览器对file://协议和http(s)://协议的访问规则完全不同,服务器上文件系统路径不等于URL路径。
为什么本地能读取,部署后就不行了
本地开发时,大部分前端项目通过Vite或Webpack Dev Server运行,本质是一个本地Node服务,浏览器访问的是http://localhost:5173这样的地址,此时你用fetch('./data.json')或axios.get('/data.json'),请求被Dev Server接管,返回的是开发服务器磁盘上的文件,所以一切正常。
项目部署到服务器之后,代码变成纯静态文件,由Nginx或Apache托管,如果你还在用fs.readFileSync这种方式(Node后端除外),或者依赖file://协议直接双击HTML打开,浏览器会直接拦截,因为页面安全策略禁止从HTTP页面读取本地文件系统,更常见的情况是,你写了fetch('./data.json'),但打包后的dist目录里根本没有这个json文件它没有被复制进构建产物。
核心问题归结为三点:json文件没有随项目一起发布、请求路径与服务器文件路径不匹配、服务器未配置正确的静态资源映射。
服务器上获取本地json的正规操作流程
第一步:把json文件放进静态资源目录
如果你用Vite构建项目,public目录下的所有文件会被原样复制到dist根目录,把data.json放到public/data.json,构建后访问https://你的域名/data.json
就能直接拿到文件,用Webpack则放在static或public目录,配置CopyWebpackPlugin确保文件被拷贝。
第二步:用相对路径发起请求
在代码里统一写相对路径,不写绝对路径:
// 推荐写法
fetch('./data.json')
.then(res => res.json())
.then(data => console.log(data))
// 或者用axios
axios.get('./data.json')
这里有个关键细节:相对路径是相对于当前页面的URL,不是相对于JS文件所在目录,如果页面路由是https://example.com/admin/page,那./data.json会请求到https://example.com/admin/data.json,解决方法是把json放在和入口HTML同级,或者使用import.meta.env.BASE_URL(Vite)等框架提供的公共路径变量拼出完整路径。
第三步:验证服务器上的json文件实际路径
部署后用浏览器直接访问https://你的域名/data.json,如果能看到json内容,说明文件到位了,如果404,先用SSH登录服务器,检查文件是否真的在Nginx root指定的目录下:
# 查看Nginx配置中的root路径 nginx -T | grep root # 到对应目录检查文件 ls -la /usr/share/nginx/html/data.json
部署到服务器后json文件读取不到的常见场景
二级目录部署,路径全乱
很多项目用https://域名/myapp/访问,此时所有相对路径请求会多出一层目录,当前页面是/myapp/index.html,fetch('./data.json')实际请求/myapp/data.json,但如果你打包配置里的base或publicPath没设置好,资源引用可能指向/data.json,导致404。
操碎心的解决办法:Vite项目在vite.config.js中设置base: '/myapp/',所有请求路径自动加上前缀,Nginx单独配置location:
location /myapp/ {
alias /var/www/myapp/;
try_files $uri $uri/ /myapp/index.html;
}
本地json文件改名或路径写死在开发环境
开发时用/src/assets/data.json,打包后这个路径不存在,正确做法是把json当作静态资源引入:
// 直接导入,打包时会被处理 import data from '@/assets/data.json'
这种方式webpack和Vite都会把json内容打包进JS,不再需要额外请求,但缺点是json更新必须重新构建项目,适合配置类小文件,不适合大数据量或高频更新的数据。
服务器部署后json跨域报错
页面在https://a.com,json放在https://b.com/data.json,浏览器会拦截跨域请求,如果两个域名都属于你,在Nginx上给存放json的服务器加跨域头:
location /data/ {
add_header Access-Control-Allow-Origin ;
add_header Access-Control-Allow-Methods 'GET, OPTIONS';
}
本地json文件读取失败时怎么排查
按这个顺序排查,多数问题十分钟内能定位:
- 打开浏览器DevTools的Network面板,看请求的URL是什么,对比实际文件路径是否正确
- 看响应状态码:404说明路径不对或文件没发布;403说明Nginx用户无权限读取文件;200但内容为空,检查文件编码是否为UTF-8无BOM
- 看Console报错:CORS错误说明跨域问题,Mixed Content说明HTTPS页面请求了HTTP资源,会被浏览器拦截
获取本地json后怎么处理缓存问题
服务器上的json文件是静态的,但浏览器会缓存它,你更新了服务器上的json内容,客户端可能还是旧数据,这在前端部署后是高频踩坑点。
解决思路:给json请求加版本号参数:
fetch(`./data.json?v=${Date.now()}`)
// 或用构建时间戳
fetch(`./data.json?v=${__BUILD_TIME__}`)
或者在Nginx上对json文件设置较短的缓存时间:
location ~ .json$ {
add_header Cache-Control "no-cache, must-revalidate";
}
这类方案在涉及服务器上json文件更新的场景非常适用,尤其是部署频率低但数据变动频繁的项目。
Q&A:项目部署到服务器上怎么获取本地的json相关常见问题
json文件打包进JS和单独请求外部json,哪种更好?
单独请求外部json更适合数据需要频繁更新、不想每次重新构建项目的场景,打包进JS减少一次网络请求,首次加载更快,但数据更新必须重新部署,选择依据是数据变动频率:一周变一次以上选外部文件,几乎不变或数据量极小选打包。
fetch和axios获取json有什么区别?
fetch是浏览器原生API,无需安装依赖,但响应处理需要手动判断response.ok,axios封装了拦截器、超时配置、错误处理,代码可读性更好,两者对服务器返回的json文件解析没有本质区别,axios底层也是XMLHttpRequest或fetch,json数据量较大时建议用axios的onDownloadProgress做加载进度提示。
服务器上的json文件被访问时返回HTML而不是json内容怎么办?
这是典型的SPA路由回退问题,Nginx配置了try_files $uri $uri/ /index.html,当json文件不存在时,请求被重写为index.html,返回的是HTML内容,Content-Type是text/html,检查项目里实际请求路径与文件存放路径是否一致,不一致优先调整代码里的路径拼接方式,Nginx的try_files配置尽量精确匹配静态资源后缀。
首发原创文章,作者:王坚,如若转载,请注明出处:https://idctop.com/article/597926.html




