跨域问题一文讲透
以下是关于跨域问题的全面解析,通过分层讲解和场景化示例帮助理解记忆:
一、跨域本质(核心概念)
1. 同源策略(Same-Origin Policy)
- 定义:浏览器安全机制,限制不同源的脚本交互
- 同源判定标准(三者完全相同):
- 协议(HTTP/HTTPS)
- 域名(www.example.com)
- 端口(:8080)
- 示例对比:
当前URL |
目标URL |
是否同源 |
http://a.com/index.html |
http://a.com/api |
✅ |
https://a.com |
http://a.com |
❌(协议不同) |
http://a.com:80 |
http://a.com:8080 |
❌(端口不同) |
2. 跨域限制范围
受限操作 |
示例场景 |
AJAX请求 |
fetch('http://b.com/data') |
Web字体加载 |
@font-face 引用外部资源 |
Canvas图像污染 |
drawImage() 外部图片 |
Cookie/LocalStorage访问 |
读取其他域存储数据 |
二、跨域解决方案全景图
1. 浏览器侧方案
方案 |
原理 |
适用场景 |
示例代码 |
JSONP |
利用<script> 标签跨域特性 |
仅需GET请求的简单场景 |
<script src="http://api.com/data?callback=handleData"></script> |
CORS |
服务端设置响应头授权 |
现代Web应用标准方案 |
response.setHeader('Access-Control-Allow-Origin', 'http://yourdomain.com') |
postMessage |
窗口间消息通信机制 |
跨窗口/iframe通信 |
otherWindow.postMessage(data, targetOrigin) |
2. 服务端方案
方案 |
原理 |
部署场景 |
配置示例 |
反向代理 |
服务端转发请求规避跨域 |
前后端分离开发环境 |
Nginx配置:
location /api { proxy_pass http://backend; } |
中间件设置CORS |
统一处理跨域头信息 |
主流Web框架集成 |
Express中间件:
app.use(cors({ origin: 'http://frontend.com' })) |
3. 协议层方案
方案 |
原理 |
适用场景 |
技术要点 |
WebSocket |
建立全双工通信通道 |
实时通信需求 |
new WebSocket('ws://api.com') |
HTTP/2 |
服务器推送+多路复用 |
现代高性能应用 |
需要TLS加密 |
三、CORS深度解析(重点方案)
1. 请求类型判定
特征 |
简单请求 |
预检请求(Preflight) |
HTTP方法 |
GET/HEAD/POST |
PUT/DELETE等 |
Content-Type |
text/plain multipart/form-data application/x-www-form-urlencoded |
application/json等 |
自定义请求头 |
无 |
有 |
2. CORS响应头详解
响应头 |
作用 |
示例值 |
Access-Control-Allow-Origin |
允许的源 |
* 或 http://yourdomain.com |
Access-Control-Allow-Methods |
允许的HTTP方法 |
GET, POST, PUT |
Access-Control-Allow-Headers |
允许的自定义请求头 |
Content-Type, Authorization |
Access-Control-Max-Age |
预检请求缓存时间(秒) |
86400 (24小时) |
Access-Control-Allow-Credentials |
是否允许携带凭证 |
true |
3. 完整CORS流程