跨域请求可以通过多种技术方案实现,核心是绕过浏览器的同源策略限制。以下是主流解决方案及具体实现方式:
一、CORS(跨域资源共享)
最常用的标准化方案,通过服务器设置HTTP响应头实现:
Access-Control-Allow-Origin: * // 允许所有域名访问(或指定域名如 https://example.com)
Access-Control-Allow-Methods: GET, POST, PUT // 允许的请求方法
Access-Control-Allow-Headers: Content-Type // 允许的请求头
Access-Control-Allow-Credentials: true // 是否允许携带Cookie(需与前端withCredentials配合)
实现步骤:
- 简单请求(GET/POST/HEAD且无自定义头)
- 浏览器自动添加
Origin
头,服务器响应Access-Control-Allow-Origin
即完成跨域。
- 浏览器自动添加
- 复杂请求(如PUT/DELETE或带自定义头)
- 浏览器先发送
OPTIONS
预检请求,服务器需响应上述头字段,通过后再发送实际请求。
适用场景:RESTful API、前后端分离项目。
- 浏览器先发送
二、JSONP(JSON with Padding)
利用<script>
标签不受同源策略限制的特性:
- 前端动态创建
<script>
标签,通过src
传递回调函数名(如?callback=handleData
)。 - 服务器返回JS代码:
handleData({ "data": "value" })
。 - 前端定义
handleData
函数处理数据。
特点:
- 仅支持GET请求
- 需服务器配合返回JS代码而非纯JSON
- 存在XSS风险,需确保来源可信。
三、反向代理
将跨域请求转发至同源代理服务器,由代理访问目标服务:
- 开发环境(如webpack/vite):
// vite.config.js export default { server: { proxy: { '/api': { target: 'http://target-domain.com', changeOrigin: true // 修改请求头Host为目标域名 } } } }
- 生产环境(Nginx配置):
location /api/ { proxy_pass http://target-domain.com/; // 转发请求 add_header Access-Control-Allow-Origin *; // 可选CORS头 }
优势:前端无需修改代码,避免CORS配置复杂度。
四、其他方案
方案 | 原理 | 局限性 |
---|---|---|
WebSocket | 建立全双工通信通道,无同源限制 | 需服务端支持WS协议 |
postMessage | window.postMessage() 实现跨窗口通信(如iframe间) | 仅适用于窗口/iframe交互 |
document.domain | 强制设置相同父域(如a.example.com 与b.example.com 均设document.domain='example.com' ) | 仅限主域相同子域不同的场景 |
五、选择建议
场景 | 推荐方案 |
---|---|
现代API接口 | CORS |
兼容老旧浏览器 | JSONP |
前端工程化项目(开发/生产) | 反向代理 |
跨域页面通信(如嵌入iframe) | postMessage |
安全提示:
- CORS避免使用
Access-Control-Allow-Origin: *
搭配敏感数据。- JSONP需防范XSS攻击,严格校验请求来源。
- 带凭证请求(Cookie/Auth)时,CORS需设置
Access-Control-Allow-Credentials: true
且Allow-Origin
不能为*
。
实际项目中,CORS与反向代理为最主流方案,兼顾安全性和易用性。