跨域
同源策略:
协议 + 域名 + 端口三者完全相同才算同源。 跨域是浏览器的安全限制,服务端之间通信不受影响。
前后端跨域
1. CORS(最主流,服务端配置)
简单请求
满足以下条件直接发送,无需预检:
- 方法:
GET、POST、HEAD - Content-Type:
text/plain、multipart/form-data、application/x-www-form-urlencoded
浏览器 ──→ 携带 Origin 头直接发请求
浏览器 ←── 服务端响应带 Access-Control-Allow-Origin
浏览器检查:当前域在允许列表中?→ 放行 / 拦截
非简单请求(触发预检)
PUT、DELETE、PATCH、或 Content-Type 为 application/json、或有自定义请求头:
浏览器 ──→ OPTIONS 预检请求(询问服务端是否允许)
浏览器 ←── 服务端返回允许配置
浏览器 ──→ 发送真实请求

2. Nginx 反向代理
原理:浏览器访问同源的 Nginx,由 Nginx 转发到后端服务。服务端之间没有跨域限制。
server {
listen 9000;
# 前端页面
location / {
proxy_pass http://localhost:3000;
}
# 接口请求转发到后端
location /api/ {
proxy_pass http://localhost:8080;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
}
}
3. dev-server 代理跨域(本地开发专用)
原理与 Nginx 一样,由开发服务器做转发,仅用于开发阶段。
Vite
// vite.config.js
export default {
server: {
proxy: {
'/api': {
target: 'http://localhost:8080',
changeOrigin: true,
rewrite: path => path.replace(/^\/api/, '')
}
}
}
}
Vue CLI(webpack)
// vue.config.js
module.exports = {
devServer: {
proxy: {
'/api': {
target: 'http://localhost:8080',
changeOrigin: true
}
}
}
}
5. WebSocket
ws 没有同源限制
const ws = new WebSocket("wss://echo.websocket.org");
4. JSONP(了解即可,已过时)
原理:<script> 标签加载资源不受同源限制,利用此特性传递数据。
// 前端
function cb(data) {
console.log(data)
}
const script = document.createElement('script')
script.src = 'http://api.example.com/data?callback=cb'
document.body.appendChild(script)
// 后端返回(执行回调函数)
cb({ code: 1, data: '...' })
缺点:
- 只支持
GET请求 - 安全性差,容易遭受 XSS 攻击
- 现代项目基本不再使用,了解原理即可
页面间跨域
1. postMessage(推荐)
用于不同窗口/iframe 之间的通信,与服务端无关。
// 发送方
const iframe = document.getElementById('iframe')
iframe.contentWindow.postMessage('hello', 'https://target.com')
// 接收方(监听 message 事件)
window.addEventListener('message', event => {
// 必须验证来源,防止恶意消息
if (event.origin !== 'https://trusted.com') return
console.log(event.data) // 消息内容
console.log(event.origin) // 发送方域名
// 回复
event.source.postMessage('received', event.origin)
})
2. document.domain(已废弃,勿用)
仅适用于主域相同、子域不同的场景(如 a.example.com ↔ b.example.com), 通过设置 document.domain = 'example.com' 来共享数据。
⚠️ 该特性已被现代浏览器废弃并逐步移除。