跨域问题是前端开发中的常见挑战,主要源于浏览器的同源策略(Same-Origin Policy)。以下是6种主流解决方案及其技术实现和适用场景分析:
原理:服务端通过HTTP头声明允许跨域的源、方法和头信息。
Access-Control-Allow-Origin: https://example.com
Access-Control-Allow-Methods: GET, POST, PUT
Access-Control-Allow-Headers: Content-Type
实现:
Access-Control-Allow-Origin
优点:支持所有HTTP方法,安全性可控 缺点:需服务端配合,旧版IE兼容性差
原理:利用<script>
标签不受同源限制的特性
function handleResponse(data) {
console.log(data);
}
const script = document.createElement('script');
script.src = 'https://api.com/data?callback=handleResponse';
document.body.appendChild(script);
服务端返回:
handleResponse({data: "value"});
优点:兼容性好,支持旧版浏览器 缺点:仅支持GET方法,存在XSS风险
实现方案:
// vue.config.js
module.exports = {
devServer: {
proxy: {
'/api': {
target: 'http://target-server.com',
changeOrigin: true
}
}
}
}
location /api/ {
proxy_pass http://target-server.com/;
proxy_set_header Host $host;
}
优点:前端无需修改代码,可集中管理请求 缺点:增加服务器负载,需维护代理服务
原理:WebSocket不受同源策略限制
const socket = new WebSocket('wss://echo.websocket.org');
socket.onmessage = (event) => {
console.log(JSON.parse(event.data));
};
适用场景:实时通信系统(聊天室、股票行情)
实现:
// 父页面 parent.example.com
document.domain = 'example.com';
// 子页面 child.example.com
document.domain = 'example.com';
限制:仅限同主域不同子域场景,需相同协议端口
原理:跨窗口消息传递
// 发送方
iframe.contentWindow.postMessage('data', 'https://target.com');
// 接收方
window.addEventListener('message', (event) => {
if (event.origin !== 'https://source.com') return;
console.log(event.data);
});
适用场景:跨域iframe通信
方案 | 适用场景 | 安全性 | 复杂度 | 兼容性 |
---|---|---|---|---|
CORS | 现代Web应用 | 高 | 中 | IE10+ |
JSONP | 旧系统兼容 | 低 | 低 | 全兼容 |
代理服务器 | 前后端分离架构 | 高 | 高 | 无限制 |
WebSocket | 实时双向通信 | 中 | 高 | IE10+ |
postMessage | 跨窗口通信 | 高 | 中 | IE8+ |
document.domain | 同主域子系统 | 中 | 低 | 全兼容 |
最佳实践:
通过合理选择跨域方案,可在保证安全性的前提下突破同源策略限制,构建高效的前后端协作体系。