CORS(跨域资源共享)是官方推荐的跨域解决方案,需在提供资源的服务器(如Nginx、Apache)中设置响应头,允许特定域名的跨域请求。
修改Nginx的配置文件(通常位于/etc/nginx/nginx.conf或/etc/nginx/sites-available/下的虚拟主机文件),在server或location块中添加以下指令:
location / {
# 允许特定域名跨域访问(替换为实际域名,避免使用*)
add_header 'Access-Control-Allow-Origin' 'https://example.com';
# 允许携带的请求头(根据实际需求调整)
add_header 'Access-Control-Allow-Headers' 'Content-Type, Authorization';
# 允许的HTTP方法(根据实际需求调整)
add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS';
# 预检请求缓存时间(单位:秒)
add_header 'Access-Control-Max-Age' 1728000;
# 处理预检请求(OPTIONS方法)
if ($request_method = 'OPTIONS') {
add_header 'Access-Control-Allow-Origin' 'https://example.com';
add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS';
add_header 'Access-Control-Allow-Headers' 'Content-Type, Authorization';
add_header 'Content-Length' 0;
return 204;
}
}
修改完成后,重启Nginx使配置生效:
sudo nginx -s reload
若使用Apache服务器,可通过.htaccess文件或虚拟主机配置添加以下指令(需启用mod_headers模块):
<IfModule mod_headers.c>
Header set Access-Control-Allow-Origin "https://example.com"
Header set Access-Control-Allow-Methods "GET, POST, OPTIONS"
Header set Access-Control-Allow-Headers "Content-Type, Authorization"
Header set Access-Control-Max-Age "3600"
</IfModule>
启用模块并重启Apache:
sudo a2enmod headers
sudo systemctl restart apache2
若无法修改目标服务器的CORS配置,可在Linux服务器上设置代理,将前端请求转发到目标服务器,从而绕过跨域限制。
假设前端运行在localhost:8080,Node.js后端运行在localhost:3000,可通过Nginx配置反向代理:
server {
listen 80;
server_name yourdomain.com; # 替换为实际域名
# 前端静态文件路径
location / {
root /path/to/frontend; # 替换为前端项目路径
try_files $uri $uri/ /index.html;
}
# 代理/api路径到后端服务器
location /api/ {
proxy_pass http://localhost:3000/; # 后端服务器地址
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection 'upgrade';
proxy_set_header Host $host;
proxy_cache_bypass $http_upgrade;
}
}
重启Nginx后,前端请求/api/路径会被转发到后端服务器,无需担心跨域问题。
若后端使用Node.js(如Express框架),可通过内置中间件或手动设置响应头解决跨域问题。
安装cors包:
npm install cors
在Express应用中启用CORS(可选择全局启用或细粒度配置):
const express = require('express');
const cors = require('cors');
const app = express();
// 全局启用CORS(允许所有域名)
app.use(cors());
// 细粒度配置(仅允许特定域名)
const corsOptions = {
origin: 'https://example.com', // 替换为实际域名
methods: 'GET,POST,PUT,DELETE',
allowedHeaders: 'Content-Type,Authorization'
};
app.use(cors(corsOptions));
app.get('/', (req, res) => {
res.send('Hello, CORS!');
});
const PORT = process.env.PORT || 3000;
app.listen(PORT, () => {
console.log(`Server running on port ${PORT}`);
});
若不想使用第三方中间件,可在路由处理前手动设置响应头:
const express = require('express');
const app = express();
app.use((req, res, next) => {
res.header('Access-Control-Allow-Origin', 'https://example.com'); // 允许的域名
res.header('Access-Control-Allow-Methods', 'GET, POST, OPTIONS'); // 允许的方法
res.header('Access-Control-Allow-Headers', 'Content-Type, Authorization'); // 允许的头
// 处理预检请求
if (req.method === 'OPTIONS') {
res.sendStatus(200);
} else {
next();
}
});
app.get('/', (req, res) => {
res.send('Hello, CORS!');
});
const PORT = process.env.PORT || 3000;
app.listen(PORT, () => {
console.log(`Server running on port ${PORT}`);
});
Access-Control-Allow-Origin: *(允许所有域名),应指定可信域名。PUT、DELETE等方法或自定义头部的请求,浏览器会先发送OPTIONS预检请求,需确保服务器正确处理(如上述Nginx和Node.js配置中的OPTIONS处理)。