浏览器跨域解决方案
浏览器跨域问题源于同源策略(Same-Origin Policy),它是浏览器重要的安全机制,限制不同源的文档或脚本进行交互。解决跨域的常用方案如下:
1. CORS (跨域资源共享)
原理:服务端设置响应头,告诉浏览器允许特定来源的请求访问资源。
适用场景:主流且安全的跨域解决方案,需服务端配合。 实现方式:
http
Access-Control-Allow-Origin: https://yourdomain.com # 允许特定域名
Access-Control-Allow-Origin: * # 允许所有域名(慎用)
Access-Control-Allow-Methods: GET, POST, PUT # 允许的请求方法
Access-Control-Allow-Headers: Content-Type, Authorization # 允许的请求头- 预检请求(Preflight):复杂请求(如带自定义头)会先发
OPTIONS请求,服务端需响应预检头。 - 携带凭证:若请求需传递 Cookie,需设置:javascript
// 前端 fetch(url, { credentials: 'include' })http// 服务端 Access-Control-Allow-Credentials: true Access-Control-Allow-Origin: https://yourdomain.com # 不能为 *
2. JSONP (JSON with Padding)
原理:利用 <script> 标签不受同源策略限制的特性,动态创建脚本获取数据。
适用场景:仅支持 GET 请求,老式浏览器兼容方案。 实现方式:
javascript
// 前端
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" });缺点:安全性低(易受 XSS 攻击),错误处理困难。
3. WebSocket
原理:ws:// 或 wss:// 协议不受同源策略限制。
适用场景:实时双向通信(如聊天室)。 实现方式:
javascript
const socket = new WebSocket('wss://api.com');
socket.onmessage = (event) => {
console.log(event.data);
};4. 代理服务器
原理:让同源服务器转发跨域请求(浏览器 → 同源代理 → 目标服务器)。
适用场景:无法修改目标服务器时(如第三方 API)。 实现方式:
- 开发环境:使用 webpack-dev-server、Vite 代理:javascript
// vite.config.js export default { server: { proxy: { '/api': { target: 'https://api.com', changeOrigin: true, } } } } - 生产环境:通过 Nginx 配置反向代理:nginx
location /api/ { proxy_pass https://api.com/; proxy_set_header Host $host; }
5. postMessage API
原理:允许不同源的窗口间安全通信(如 iframe 与父页面)。
适用场景:跨窗口/跨 Tab 通信。 实现方式:
javascript
// 发送方(iframe 内部)
parent.postMessage('Hello', 'https://parent-domain.com');
// 接收方(父页面)
window.addEventListener('message', (event) => {
if (event.origin !== 'https://iframe-domain.com') return;
console.log(event.data); // 'Hello'
});6. 修改 document.domain
原理:强制让两个页面拥有相同的基础域名(如 a.example.com 和 b.example.com 都设为 example.com)。
适用场景:仅限主域相同、子域不同的情况。 实现方式:
javascript
// 两个页面都设置
document.domain = 'example.com';注意:现代浏览器已逐渐弃用此方案。
7. CORS 代理服务(第三方)
原理:使用公共代理服务(如 cors-anywhere)中转请求。
适用场景:临时测试或无法自建代理时。 示例:
javascript
fetch('https://cors-anywhere.herokuapp.com/https://api.com/data')总结对比
| 方案 | 适用场景 | 是否需要服务端配合 | 安全性 | 请求类型 |
|---|---|---|---|---|
| CORS | 主流跨域方案 | 是 | ⭐⭐⭐⭐⭐ | 所有 HTTP 方法 |
| JSONP | 兼容老旧系统 | 是(需支持回调) | ⭐⭐ | 仅 GET |
| 代理服务器 | 无法修改目标服务器时 | 否(自建代理) | ⭐⭐⭐⭐ | 所有方法 |
| WebSocket | 实时双向通信 | 是 | ⭐⭐⭐⭐ | 双向通信 |
| postMessage | 跨窗口通信 | 否 | ⭐⭐⭐⭐ | 自定义消息 |
关键建议:
- 优先使用 CORS(安全且标准化)。
- 开发环境用 代理 避免跨域问题。
- 避免使用
*开放 CORS,应明确指定可信域名。- 敏感操作(如 Cookie)务必设置
Access-Control-Allow-Credentials: true并限制来源域名。
根据实际场景选择合适的方案,可高效解决跨域问题并保障安全性。