前端analysis | 知其所以然

前端跨域

2025-05-21

🌐 什么是跨域(CORS)

跨域(Cross-Origin):当前网页的 JS 在向不同源发起请求时,如果协议、域名、端口任一不相同,就会被认为是“跨域”。

举个例子:


🔒 同源策略限制内容

浏览器会限制以下行为:

  • XMLHttpRequest / fetch 请求被拦截
  • 读取跨域响应数据 会失败(即便请求成功)
  • 部分 cookielocalStorage 等也受限

✅ 常见跨域解决方案

1. CORS(Cross-Origin Resource Sharing)

最推荐的方式,由服务端设置响应头允许跨域访问。

服务端设置响应头(示例):

1
2
3
4
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

优点:

  • 标准、安全
  • 支持多种请求方式

缺点:

  • 需要服务端配合设置

2. JSONP(仅支持 GET 请求)

原理:利用 <script> 标签没有跨域限制的特性,通过动态插入 <script> 实现跨域数据请求。

使用方式:

1
2
3
4
5
6
7
<script src="https://api.example.com/data?callback=handleData"></script>

<script>
function handleData(data) {
console.log(data);
}
</script>

优点:

  • 兼容老浏览器

缺点:

  • 只支持 GET
  • 不安全,不推荐用于现代项目

3. 代理转发(开发时最常用)

在本地开发时,可以使用 Webpack/Vite 配置代理,将请求转发到目标 API,避免浏览器发起跨域请求。

Vite 配置示例:

1
2
3
4
5
6
7
8
9
10
11
12
// vite.config.js
export default {
server: {
proxy: {
'/api': {
target: 'https://api.example.com',
changeOrigin: true,
rewrite: path => path.replace(/^\/api/, '')
}
}
}
}

优点:

  • 开发方便
  • 无需改动后端

缺点:

  • 仅适用于开发环境

4. 服务器中间层代理(后端转发)

后端自己请求外部 API,再返回给前端,前端请求的始终是同源接口。

原理图:

1
前端 ——> 自己服务器 ——> 外部 API

优点:

  • 彻底规避跨域
  • 可控制缓存、安全性

缺点:

  • 增加服务器负担

5. window.postMessage(用于 iframe 跨域通信)

用于两个不同源的页面之间通过 iframe 或 window.open 传递消息。

1
2
3
4
5
6
7
8
9
// 子页面
window.parent.postMessage('data from child', 'https://parent.com');

// 父页面监听
window.addEventListener('message', (event) => {
if (event.origin === 'https://child.com') {
console.log(event.data);
}
});

🧠 总结推荐

方式 适用场景 是否安全 支持请求类型 是否需后端
CORS 推荐方式 ✅ 安全 所有
JSONP 老项目/兼容需求 ❌ 不安全 GET
本地代理 本地开发 ✅ 安全 所有
服务端代理 所有场景 ✅ 安全 所有
postMessage 页面嵌套 ✅ 安全 -

Nginx 也是一种 常见且强大 的跨域解决方案,适用于生产环境中通过 反向代理 来解决跨域问题,或者通过配置 CORS 响应头 来支持跨域访问。


🔁 一、Nginx 解决跨域的两种方式


✅ 方式一:反向代理跨域(推荐)

通过 Nginx 把前端请求代理到后端服务器,前端请求的是同源地址,从而避免跨域。

📌 示例场景:

  • 前端页面:https://www.my-site.com
  • 后端 API:https://api.example.com
  • Nginx 配置反向代理 /apihttps://api.example.com

🛠 Nginx 配置示例:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
server {
listen 80;
server_name www.my-site.com;

location / {
root /usr/share/nginx/html;
index index.html;
}

location /api/ {
proxy_pass https://api.example.com/;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}
}

🔄 这样浏览器看到的是同一个源 www.my-site.com,跨域问题就不存在了。


✅ 方式二:添加 CORS 响应头

如果你控制的是 API 服务所在的 Nginx,可以直接配置 CORS 响应头,允许跨域访问。

🛠 Nginx 配置 CORS 示例:

1
2
3
4
5
6
7
8
9
10
11
location /api/ {
add_header 'Access-Control-Allow-Origin' '*' always;
add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS';
add_header 'Access-Control-Allow-Headers' 'Content-Type, Authorization';

if ($request_method = 'OPTIONS') {
return 204;
}

proxy_pass http://backend_api;
}

📌 说明:

  • Access-Control-Allow-Origin: * 允许所有域访问(可以换成具体域名)
  • OPTIONS 请求用于预检请求(preflight),所以要返回 204(No Content)

🧠 Nginx 配置总结对比

跨域方式 应用层 是否需改动后端 安全性 复杂度 优点 缺点
✅ Nginx 反向代理 服务器 ❌(只改 Nginx) 高效、可控、生产可用 需配置服务器、维护代理路径
✅ CORS 响应头 后端 ✅ 需要支持 标准、安全 后端需支持、预检可能耗性能
⚠️ JSONP 前端+后端 ✅ 需要接口支持 简单、支持老浏览器 仅支持 GET,存在 XSS 风险
✅ 本地开发代理 前端构建工具 配置简单,开发方便 仅限开发环境,生产不适用
✅ 服务端代理 后端 ✅(自己转发) 中高 可控制安全与缓存 增加服务压力,维护成本
✅ postMessage 前端 跨窗口安全通信 场景有限,仅适合 iframe
使用支付宝打赏
使用微信打赏

若你觉得我的文章对你有帮助,欢迎点击上方按钮对我打赏