前端跨域 CORS 报错怎么解决:全场景排查与修复指南
前端跨域 CORS 报错怎么解决
CORS(跨域资源共享)报错的根本原因是浏览器的同源策略,它拦截了前端脚本对非同源接口的响应。解决 CORS 报错,我一般先看具体报错类型,然后针对性地调整服务端响应头或前端请求配置,绝大多数情况下不需要绕路。核心结论是:CORS 是安全机制,必须通过合法配置解决,而非绕过。
什么是 CORS 报错
CORS 是浏览器安全机制,禁止前端页面向非同源接口发送请求或读取响应,除非服务端明确授权。我遇到 CORS 报错时,浏览器控制台通常会显示类似这样的错误:
Access to fetch at 'https://api.example.com/data' from origin 'http://localhost:3000' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource.
常见报错类型有四种:
- Basic CORS error:缺少
Access-Control-Allow-Origin头 - Credentials flag error:请求携带凭证时,服务端未设置
Access-Control-Allow-Credentials: true - Pre-flight error:复杂请求(如 POST 带自定义头)的 OPTIONS 预检失败
- Header mismatch error:服务端返回的
Allow-Headers或Allow-Methods不包含实际请求内容
服务端如何修复 CORS
服务端是解决问题的关键方,我常用 Node.js 的 cors 中间件处理,它在 Express、Fastify 等框架中都能无缝集成。
安装依赖:
npm install cors
基础配置:
const express = require('express');
const cors = require('cors');
const app = express();
// 允许所有来源(开发环境可用,生产环境需谨慎)
app.use(cors());
// 指定特定来源
app.use(cors({
origin: 'http://localhost:3000',
methods: ['GET', 'POST'],
allowedHeaders: ['Content-Type', 'Authorization']
}));
app.get('/data', (req, res) => {
res.json({ message: 'success' });
});
如果后端是 Go 语言,我会用原生方式设置响应头:
func corsMiddleware(next http.Handler) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
w.Header().Set("Access-Control-Allow-Origin", "http://localhost:3000")
w.Header().Set("Access-Control-Allow-Methods", "GET, POST, OPTIONS")
w.Header().Set("Access-Control-Allow-Headers", "Content-Type, Authorization")
if r.Method == "OPTIONS" {
w.WriteHeader(http.StatusOK)
return
}
next.ServeHTTP(w, r)
})
}
前端常见配置陷阱
前端代码有时也会引发 CORS 问题,我遇到过这些典型情况:
1. 忘记设置 credentials 字段 当服务端要求携带 Cookie 时,前端必须显式声明:
fetch('https://api.example.com/user', {
method: 'POST',
credentials: 'include', // 关键配置
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify({ name: 'Alice' })
});
2. 使用了非简单请求方法
POST 请求体如果不是 application/x-www-form-urlencoded、multipart/form-data 或 text/plain,就会触发预检请求。如果服务端没有正确处理 OPTIONS 请求,就会报错。
3. 自定义 Header 未声明
发送 Authorization 或 X-Request-ID 等自定义头时,必须确保服务端在 Access-Control-Allow-Headers 中声明:
headers: {
'Content-Type': 'application/json',
'Authorization': 'Bearer token123', // 需要服务端 Allow-Headers 包含此头
'X-Request-ID': 'abc-123' // 同样需要声明
}
开发环境代理方案
在本地开发时,我倾向于用 Vite 或 Webpack 的 proxy 功能,完全避开 CORS 问题。这是最干净的解决方案:
Vite 配置(vite.config.js):
export default defineConfig({
server: {
proxy: {
'/api': {
target: 'https://api.example.com',
changeOrigin: true,
secure: false
}
}
}
});
这样前端请求 /api/data 会直接代理到 https://api.example.com/api/data,同源策略不再拦截。生产环境需要 Nginx 做类似配置。
总结排查思路
遇到 CORS 报错时,我会按这个顺序排查:
- 看报错具体类型,确认是简单请求还是预检失败
- 检查服务端是否设置了正确的
Access-Control-Allow-Origin - 确认请求头、方法都在
Allow-Headers和Allow-Methods范围内 - 生产环境检查
credentials和origin是否匹配
如果服务端无法修改,开发环境代理是最实用的临时方案。
本文首发于 前端跨域 CORS 报错怎么解决:全场景排查与修复指南 — https://lyxq.com.cn/en/blog/frontend-cors-error-solution
转载或引用请注明出处,商业使用请联系作者获得授权。