React请求AWS EC2上的Express服务报Failed to fetch错误
问题定位
你的EC2安全组配置完全正确,这个报错和AWS侧安全规则无关,是浏览器同源策略触发的CORS(跨域资源共享)拦截。
- 直接在浏览器地址栏访问EC2域名、用Postman发请求不受同源策略约束,只要网络连通、服务正常就能拿到响应,这也是这两种方式能通的原因
- 本地React应用运行在
http://localhost:3000,请求目标是http://ec2-xxx-xxx-xxx-xxx.xxxxx.amazonaws.com,二者域名不一致,属于跨域请求。浏览器会默认拦截这类请求的响应,前端侧只会抛出TypeError: Failed to fetch,不会直接透出底层的CORS拦截细节。
另外你贴的Express服务代码末尾多了一段冗余的})(),本身存在语法错误,启动服务的时候会直接报错,修复的时候要一并删掉。
修复方法
方案1:服务端配置CORS头(开发、生产环境通用)
直接给Express服务添加跨域响应头,是最彻底的解决方式:
- 进入Express项目目录,安装cors中间件:
npm install cors
- 修改服务端入口文件
index.js,引入并启用cors中间件,修正后代码如下:
// index.js (express js server) import express from 'express' import cors from 'cors' const app = express() // 测试阶段可直接放开所有跨域来源,生产环境建议替换为你实际部署前端的域名做白名单 app.use(cors()) app.get('/', async (req, res) => { res.json({ data: 'hello world' }) }) const Port = '80' app.listen(Port, () => { console.log(`server is running on ${Port}`) })
- 重启Express服务,前端重新发请求即可正常拿到响应。
方案2:本地开发配置代理(仅本地调试用,无需改服务端)
如果暂时不方便修改服务端配置,可以利用create-react-app内置的代理能力规避跨域:
- 打开React项目根目录下的
package.json,添加一行代理配置:
{ // 保留你原有的所有配置项,只新增下面这行 "proxy": "http://ec2-xxx-xxx-xxx-xxx.xxxxx.amazonaws.com" }
- 把前端的fetch请求改成相对路径:
const response = await fetch("/");
- 重启React本地开发服务,请求会被开发服务代理转发到EC2的Express接口,不会触发跨域拦截。注意这个方案只在本地
npm start跑开发服务的时候生效,前端打包部署后无效,生产环境还是要走服务端CORS配置。
验证方式
修改后如果仍有问题,打开浏览器开发者工具的「控制台」面板,如果看到类似No 'Access-Control-Allow-Origin' header is present on the requested resource的报错,即可100%确认是跨域配置问题,和EC2网络、安全组无关。
内容的提问来源于stack exchange,提问作者code
相关产品推荐
相关产品推荐

