以下是前端解决跨域问题的 7 种主流方案,根据应用场景和实现难度排序,附详细实现示例:
一、开发环境解决方案
1. Webpack DevServer 代理(推荐)
// vue.config.js / webpack.config.js
module.exports = {devServer: {proxy: {'/api': {target: 'http://backend-domain.com', // 后端地址changeOrigin: true, // 修改请求头HostpathRewrite: { '^/api': '' } // 路径重写}}}
}
原理:前端请求 /api/users
→ DevServer 转发到 http://backend-domain.com/users
2. 浏览器禁用安全策略(临时调试)
# macOS
open -n -a "Google Chrome" --args --disable-web-security --user-data-dir=/tmp/chrome# Windows 快捷方式属性追加
chrome.exe --disable-web-security --user-data-dir="C:/temp"
注意:仅限本地开发,需关闭所有 Chrome 实例后执行
二、生产环境解决方案
3. Nginx 反向代理
server {listen 80;server_name your-domain.com;location /api {proxy_pass http://backend-ip:8080; # 后端服务地址proxy_set_header Host $host;proxy_set_header X-Real-IP $remote_addr;}location / {root /usr/share/nginx/html; # 前端静态资源try_files $uri $uri/ /index.html;}
}
优势:前后端同域,天然避免跨域问题
4. CORS(跨域资源共享)
需后端配合设置响应头:
Access-Control-Allow-Origin: https://your-frontend.com
Access-Control-Allow-Methods: GET, POST, PUT
Access-Control-Allow-Headers: Content-Type, Authorization
Access-Control-Allow-Credentials: true # 允许携带Cookie
前端代码示例:
// 需要携带凭证时
fetch('https://api-domain.com/data', {credentials: 'include' // 或 'same-origin'
});
三、特殊场景方案
5. JSONP(仅限 GET 请求)
function jsonp(url, callback) {const script = document.createElement('script');script.src = `${url}?callback=${callback}`;document.body.appendChild(script);
}// 后端需返回:callbackName({ data: ... })
jsonp('http://backend.com/api', 'handleResponse');function handleResponse(data) {console.log('Received:', data);
}
6. WebSocket
const socket = new WebSocket('ws://backend-domain.com/socket');socket.onmessage = (event) => {console.log('Received:', JSON.parse(event.data));
};// 发送消息
socket.send(JSON.stringify({ action: 'getData' }));
7. postMessage(跨窗口通信)
主窗口:
// 发送消息到 iframe
document.querySelector('iframe').contentWindow.postMessage({ type: 'request', data: '需要传输的数据' },'https://target-domain.com'
);
iframe 接收方:
window.addEventListener('message', (event) => {if (event.origin !== 'https://parent-domain.com') return;console.log('Received:', event.data);
});
方案对比表
方案 | 适用场景 | 是否需要后端配合 | 安全性 | 请求类型支持 |
---|---|---|---|---|
DevServer 代理 | 本地开发 | 否 | 高 | 所有 |
Nginx 代理 | 生产环境 | 否 | 高 | 所有 |
CORS | 生产环境 | 是 | 中 | 所有 |
JSONP | 旧浏览器兼容 | 是 | 低 | 仅 GET |
WebSocket | 实时通信 | 是 | 高 | 双向通信 |
postMessage | 跨窗口通信 | 否 | 中 | 自定义消息 |
禁用浏览器安全策略 | 本地临时调试 | 否 | 极低 | 所有 |
最佳实践建议
- 开发阶段:优先使用 Webpack DevServer 代理
- 生产环境:
- 首选 Nginx 反向代理
- 需要多后端服务时使用 CORS
- 特殊需求:
- 实时通信 → WebSocket
- 旧系统兼容 → JSONP
- 安全规范:
- 避免使用
Access-Control-Allow-Origin: *
- 敏感接口需要 CORS + 身份验证双重保护
- 避免使用
可根据实际项目需求组合使用多种方案,如开发环境用代理 + 生产环境用 Nginx + 特殊接口用 CORS。