React.js应用连接Node.js服务器的最佳方式?如何解决CORS跨域报错
问题解答
现有实现是否符合最佳实践
你当前使用Axios发送POST请求提交表单的写法符合前端请求的基本最佳实践,本次报错和前端代码无关,是服务端跨域资源共享(CORS)配置缺失导致的。
报错原因解释
你的React应用运行在http://localhost:3001,NodeJS服务运行在http://localhost:3000,端口不同属于不同源站点,浏览器的同源策略默认会阻止跨源的HTTP请求,需要服务端返回对应的CORS响应头放行前端的请求。
解决方案
方案1:Node服务端配置CORS(推荐,适配开发+生产环境)
如果你使用Express作为Node服务框架,有两种配置方式:
- 方式一:使用官方
cors中间件(最简便)- 安装依赖:
npm install cors - 在服务端入口文件添加配置:
const express = require('express'); const cors = require('cors'); const app = express(); // 开发环境可放行前端地址,生产环境替换为线上前端域名 app.use(cors({ origin: 'http://localhost:3001', credentials: true // 如果需要传递Cookie等凭证可以开启 })); - 安装依赖:
- 方式二:手动配置响应头(无需第三方依赖)
在服务端路由之前添加全局中间件:app.use((req, res, next) => { res.header('Access-Control-Allow-Origin', 'http://localhost:3001'); res.header('Access-Control-Allow-Methods', 'GET, POST, PUT, DELETE, OPTIONS'); res.header('Access-Control-Allow-Headers', 'Content-Type, Authorization'); // 预检OPTIONS请求直接返回成功状态 if (req.method === 'OPTIONS') { return res.sendStatus(200); } next(); });
方案2:React开发环境代理(仅适配本地开发)
如果你用Create React App初始化的项目,可以直接在package.json中添加配置:
"proxy": "http://localhost:3000"
之后前端发请求时不需要写完整的服务端域名,直接写路径即可,比如axios.post('/api/v1/users/signup', data),开发服务器会自动把请求代理到后端服务,不会触发跨域校验。生产环境可以配合Nginx反向代理,把前后端接口统一到同一个域名下,从根源避免跨域问题。
现有代码的优化建议
你可以在现有写法基础上做以下优化,更符合生产级最佳实践:
- 请求地址用环境变量管理,不要硬编码,方便区分开发/生产环境
- catch分支不要仅打印错误日志,要添加用户可见的错误提示,比如登录失败的toast提示
- 拿到返回的token后建议存储在HttpOnly属性的Cookie中,避免XSS攻击窃取凭证
内容的提问来源于stack exchange,提问作者Ashutosh Saini
相关产品推荐
相关产品推荐

