CORS 跨域完全指南:原理、解决方案与最佳实践
跨域是前端开发中最常见的问题之一。本文深入介绍 CORS 的原理和解决方案。
什么是跨域?
当协议、域名、端口任一不同时,就是跨域。
http://localhost:3000 → http://localhost:8080 (端口不同)
http://example.com → https://example.com (协议不同)
http://a.com → http://b.com (域名不同)
CORS 原理
CORS(Cross-Origin Resource Sharing)是浏览器的安全机制。
简单请求
// GET/POST/HEAD,简单头部
fetch('http://api.example.com/data')
浏览器直接发送请求,服务器返回 Access-Control-Allow-Origin 头。
预检请求
// PUT/DELETE 或自定义头部
fetch('http://api.example.com/data', {
method: 'PUT',
headers: { 'Content-Type': 'application/json' }
})
浏览器先发送 OPTIONS 预检请求,服务器确认允许后再发送实际请求。
解决方案
1. 后端配置 CORS
Spring Boot:
@Configuration
public class CorsConfig implements WebMvcConfigurer {
@Override
public void addCorsMappings(CorsRegistry registry) {
registry.addMapping("/**")
.allowedOrigins("*")
.allowedMethods("GET", "POST", "PUT", "DELETE")
.allowedHeaders("*")
.maxAge(3600);
}
}
Node.js:
const cors = require('cors');
app.use(cors({
origin: '*',
methods: ['GET', 'POST', 'PUT', 'DELETE']
}));
2. Nginx 反向代理
server {
listen 80;
server_name example.com;
location /api/ {
proxy_pass http://localhost:8080/;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
}
}
3. 开发环境代理
Vite:
// vite.config.js
export default defineConfig({
server: {
proxy: {
'/api': {
target: 'http://localhost:8080',
changeOrigin: true
}
}
}
})
最佳实践
- 生产环境使用 Nginx 反向代理:避免 CORS 问题
- 限制允许的源:不要使用
* - 缓存预检请求:设置
maxAge - HTTPS:使用 HTTPS 避免混合内容
总结
CORS 是浏览器的安全机制。通过后端配置、Nginx 代理、开发环境代理等方式,可以解决跨域问题。