React生产构建后打开index.html遇CORS错误,求解决方案
React生产构建后直接打开index.html的CORS错误问题
问题现象
使用npm run build构建React生产环境应用后,直接打开生成的index.html文件,控制台抛出CORS错误:
Access to manifest at 'file:///Users/nanditasingh/Documents/workspace/dashboard-app/manifest.json' from origin 'null' has been blocked by CORS policy: Cross origin requests are only supported for protocol schemes: http, data, isolated-app, chrome-extension, chrome, https, chrome-untrusted
问题原因
- 协议限制:直接通过
file://协议打开本地HTML文件时,浏览器会将页面源标记为null,而浏览器的CORS策略仅允许http/https等标准网络协议发起资源请求,file://不在允许范围内,因此拦截了manifest.json的加载请求。 - 跨域属性加剧冲突:你的
index.html中给manifest链接添加了crossorigin="use-credentials"属性,这会触发浏览器对manifest文件发起带凭证的跨源请求,在file://协议下进一步放大了CORS冲突。
解决办法
方法1:用本地静态服务器运行构建产物(推荐)
模拟生产环境的HTTP服务,彻底规避file://协议的限制:
- Python方式:进入
build目录执行对应命令- Python 3:
python -m http.server 3000 - Python 2:
python -m SimpleHTTPServer 3000
- Python 3:
- Node.js方式:使用
serve包- 全局安装:
npm install -g serve - 项目根目录执行:
serve -s build
- 全局安装:
- 完成后在浏览器访问
http://localhost:3000即可正常加载应用。
方法2:移除manifest的跨域属性(临时测试用)
打开项目源码中的public/index.html(非build后的文件),将manifest链接的crossorigin="use-credentials"属性删除,改为:
<link rel="manifest" href="./manifest.json" />
重新构建后,可消除manifest的CORS错误,但file://协议下仍可能存在其他资源加载问题,仅适合临时验证。
方法3:部署到线上服务器(生产环境标准做法)
将build目录的文件上传至支持http/https的服务器(如Nginx、Apache,或通过你配置的gh-pages部署),通过域名访问即可完全避免CORS问题。
相关配置代码
manifest.json
{ "short_name": "React App", "name": "Create React App Sample", "icons": [ { "src": "favicon.ico", "sizes": "64x64 32x32 24x24 16x16", "type": "image/x-icon" }, { "src": "logo192.png", "type": "image/png", "sizes": "192x192" }, { "src": "logo512.png", "type": "image/png", "sizes": "512x512" } ], "start_url": ".", "display": "standalone", "theme_color": "#000000", "background_color": "#ffffff" }
index.html(构建后)
<!DOCTYPE html> <html lang="en"> <head> <meta charset="utf-8" /> <link rel="icon" href="./favicon.ico" /> <meta name="viewport" content="width=device-width,initial-scale=1" /> <meta name="theme-color" content="#000000" /> <meta name="description" content="Web site created using create-react-app" /> <link rel="apple-touch-icon" href="./logo192.png" /> <link rel="manifest" href="./manifest.json" crossorigin="use-credentials" /> <title>React App</title> <script defer="defer" src="./static/js/main.f8df3b0f.js"></script> <link href="./static/css/main.1665f4d8.css" rel="stylesheet" /> </head> <body> <noscript>You need to enable JavaScript to run this app.</noscript> <div id="root"></div> </body> </html>
package.json(scripts部分)
"scripts": { "start": "react-scripts start", "predeploy": "npm run build", "deploy": "gh-pages -d build", "build": "react-scripts build", "test": "react-scripts test", "eject": "react-scripts eject" },
内容的提问来源于stack exchange,提问作者Nandita Singh
相关产品推荐
相关产品推荐

