React使用Axios向后端传数据触发CORS跨域报错如何解决
这是典型的浏览器CORS跨域拦截,和你写的React组件、Axios请求逻辑没有关系。Postman能调通接口是因为Postman不受浏览器同源策略限制,你的前端跑在http://localhost:1234,后端跑在http://localhost:8070,端口不一致属于跨源请求,浏览器会自动拦截没有携带合法CORS响应头的跨域请求。
报错里明确说明预检OPTIONS请求没有拿到Access-Control-Allow-Origin响应头,就是后端没配置跨域允许规则导致的。
方案1:前端配置本地开发代理(仅本地开发环境可用)
如果是Vite创建的React项目,直接在根目录vite.config.js里添加代理配置,不需要改动业务代码里的请求逻辑:
import { defineConfig } from 'vite' import react from '@vitejs/plugin-react' export default defineConfig({ plugins: [react()], server: { proxy: { '/products': { target: 'http://localhost:8070', changeOrigin: true, } } } })
配置完成后,把所有Axios请求里的http://localhost:8070前缀删掉,比如axios.post("http://localhost:8070/products/", data)改成axios.post("/products/", data),重启前端开发服务即可绕过浏览器跨域检查。
如果是Create React App创建的项目,先安装http-proxy-middleware依赖,在根目录新建setupProxy.js文件写入以下配置:
const { createProxyMiddleware } = require('http-proxy-middleware'); module.exports = function(app) { app.use( '/products', createProxyMiddleware({ target: 'http://localhost:8070', changeOrigin: true, }) ); };
方案2:后端配置全局CORS规则(生产环境必须使用)
跨域拦截的核心校验逻辑在浏览器侧,只有后端返回符合要求的CORS响应头才能彻底解决问题,根据你用的后端框架选对应配置即可:
- Node.js + Express框架:
先安装cors依赖npm install cors,在服务入口文件添加全局中间件:const cors = require('cors') // 开发环境临时用:允许所有源访问 app.use(cors()) // 生产环境建议指定允许的前端源,避免接口被任意站点调用 // app.use(cors({ origin: "http://你的前端线上域名", credentials: true })) - Spring Boot框架:
新增CORS全局配置类:@Configuration public class CorsConfig implements WebMvcConfigurer { @Override public void addCorsMappings(CorsRegistry registry) { registry.addMapping("/**") .allowedOriginPatterns("*") .allowedMethods("GET", "POST", "PUT", "DELETE", "OPTIONS") .allowedHeaders("*") .allowCredentials(true) .maxAge(3600); } } - Python Django框架:
先安装django-cors-headers依赖,修改settings.py配置:INSTALLED_APPS = [ ... 'corsheaders', ... ] MIDDLEWARE = [ ... 'corsheaders.middleware.CorsMiddleware', 'django.middleware.common.CommonMiddleware', ... ] # 开发环境临时允许所有源 CORS_ALLOW_ALL_ORIGINS = True
配置完成后重启后端服务,前端不需要修改请求地址,直接调用http://localhost:8070的接口就不会再触发跨域拦截。
你现有代码里混用了async/await和.then/.catch异步写法,比如const insert = await axios.post().then(),这种写法没有必要,统一使用其中一种即可,避免出现隐式异步逻辑问题,不过这部分不是触发本次跨域报错的原因。
内容的提问来源于stack exchange,提问作者Sachin Wimansa

