本文目录导读:
我来给你提供几个典型的CORS(跨域资源共享)案例,从简单到复杂,帮助你理解各种场景。
最基本的前后端分离
场景
前端运行在 http://localhost:3000,后端API运行在 http://localhost:8080。
问题
浏览器发起请求时出现CORS错误。
后端解决方案(Node.js/Express)
// 最简单的CORS配置
const express = require('express');
const app = express();
app.use((req, res, next) => {
res.header('Access-Control-Allow-Origin', '*');
next();
});
app.get('/api/data', (req, res) => {
res.json({ message: 'CORS配置成功!' });
});
app.listen(8080);
指定域名 + 凭据
场景
- 前端:
https://www.myapp.com - 后端:
https://api.myapp.com - 需要携带Cookie
配置(重点)
app.use((req, res, next) => {
// 只允许特定域名访问
res.header('Access-Control-Allow-Origin', 'https://www.myapp.com');
// 允许携带凭证(Cookie)
res.header('Access-Control-Allow-Credentials', 'true');
// 允许的请求头
res.header('Access-Control-Allow-Headers',
'Content-Type, Authorization, X-Custom-Header');
// 允许的请求方法
res.header('Access-Control-Allow-Methods',
'GET, POST, PUT, DELETE, PATCH, OPTIONS');
// 预检请求缓存时间(秒)
res.header('Access-Control-Max-Age', '86400');
// 处理预检请求
if (req.method === 'OPTIONS') {
return res.sendStatus(200);
}
next();
});
动态多域名支持
场景
多个前端域名需要访问同一个API。
解决方案
const express = require('express');
const app = express();
// 允许的域名白名单
const allowedOrigins = [
'https://www.myapp.com',
'https://admin.myapp.com',
'http://localhost:3000'
];
app.use((req, res, next) => {
const origin = req.headers.origin;
// 检查请求来源是否在白名单中
if (allowedOrigins.includes(origin)) {
res.header('Access-Control-Allow-Origin', origin);
res.header('Access-Control-Allow-Credentials', 'true');
}
res.header('Access-Control-Allow-Headers',
'Content-Type, Authorization');
res.header('Access-Control-Allow-Methods',
'GET, POST, PUT, DELETE, PATCH, OPTIONS');
if (req.method === 'OPTIONS') {
return res.sendStatus(200);
}
next();
});
// 业务接口
app.get('/api/users', (req, res) => {
res.json({ users: ['Alice', 'Bob', 'Charlie'] });
});
app.listen(8080);
携带JWT Token的请求
场景
前端需要发送带Authorization头部的请求。
前端代码
// fetch 请求
fetch('https://api.myapp.com/api/private-data', {
method: 'GET',
credentials: 'include', // 如果使用Cookie
headers: {
'Authorization': `Bearer ${token}`,
'Content-Type': 'application/json'
}
});
// axios 请求
axios.get('https://api.myapp.com/api/private-data', {
withCredentials: true, // 如果使用Cookie(改为withCredentials,而非credentials)
headers: {
'Authorization': `Bearer ${token}`
}
});
后端响应头
res.header('Access-Control-Allow-Origin', 'https://myapp.com');
res.header('Access-Control-Allow-Headers', 'Content-Type, Authorization');
res.header('Access-Control-Expose-Headers', 'Authorization');
完整的前端错误处理
场景
前端正确处理CORS错误和响应。
async function fetchData() {
try {
const response = await fetch('https://api.myapp.com/api/data', {
method: 'POST',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify({ type: 'test' })
});
if (!response.ok) {
throw new Error(`HTTP error! status: ${response.status}`);
}
const data = await response.json();
console.log('成功获取数据:', data);
} catch (error) {
if (error instanceof TypeError) {
console.error('CORS错误或网络错误:', error.message);
// 具体判断是否是CORS错误
if (error.message.includes('Failed to fetch')) {
showCorsErrorMessage();
}
} else {
console.error('其他错误:', error.message);
}
}
}
function showCorsErrorMessage() {
alert('跨域请求失败:请检查服务器CORS配置');
}
使用第三方库(cors包)
最优雅的解决方案
const express = require('express');
const cors = require('cors');
const app = express();
// 配置选项
const corsOptions = {
origin: function (origin, callback) {
// 定义允许的来源列表
const whitelist = [
'https://myapp.com',
'https://admin.myapp.com'
];
// 允许无来源的请求(如移动应用、Postman等)
if (!origin || whitelist.indexOf(origin) !== -1) {
callback(null, true);
} else {
callback(new Error('不允许的来源'));
}
},
credentials: true, // 允许携带Cookie
methods: ['GET', 'POST', 'PUT', 'DELETE', 'PATCH', 'OPTIONS'],
allowedHeaders: ['Content-Type', 'Authorization'],
maxAge: 86400 // 预检请求缓存24小时
};
// 全局应用
app.use(cors(corsOptions));
// 或对特定路由应用
app.get('/api/special', cors(corsOptions), (req, res) => {
res.json({ message: '这是受CORS保护的接口' });
});
app.listen(8080);
调试技巧
使用Chrome开发者工具
- 打开Console查看错误信息
- 在Network中查看请求的Headers
快速诊断方法
// 检查Response Headers中是否有: Access-Control-Allow-Origin: * Access-Control-Allow-Credentials: true
常用测试工具
- Postman (不会触发CORS,但可测试API功能)
- chrome 的 cors 插件
curl命令
常见问题快速参考
| 错误信息 | 问题原因 | 解决方案 |
|---|---|---|
| "No 'Access-Control-Allow-Origin' header is present" | 后端未配置CORS | 后端添加CORS头 |
| "Request header field authorization is not allowed" | 跨域预检失败 | 允许对应头部 |
| Credentials mode is 'include'" | 携带Cookie问题 | 配置credentials |
| "Network Error" | 网络或CORS问题 | 检查网络和CORS配置 |
这些案例覆盖了绝大多数日常开发中遇到的CORS问题,根据你的具体场景选择对应的配置方式即可,如果有特别复杂的场景,欢迎告诉我具体需求。