深入理解服务器与客户端 JS 跨域问题
什么是跨域?
跨域(Cross-Origin) 是指浏览器出于安全考虑,限制从一个域名、协议或端口加载的脚本请求另一个域名、协议或端口的资源,这种安全机制被称为 同源策略(Same-Origin Policy)。
同源 的定义是:协议(Protocol)、域名(Domain)、端口(Port) 三者必须完全一致,只要其中任何一项不同,浏览器就会判定为跨域。
- 同源示例:
http://example.com/a.js$rightarrow$http://example.com/b.js - 跨域示例:
- 协议不同:
http://$rightarrow$https:// - 域名不同:
example.com$rightarrow$api.example.com - 端口不同:
80$rightarrow$8080
- 协议不同:
为什么会有跨域限制?
同源策略是为了防止恶意网站通过脚本窃取用户的敏感数据,如果没有这个限制,任何网站都可以通过 JS 发起请求到你的银行网站或社交账号,如果用户处于登录状态,恶意脚本可能会在后台发送请求修改密码或窃取个人信息。
常见的解决方案
解决跨域的核心思路分为:服务器端配置(正统方案)和 客户端/中间层代理(开发环境常用方案)。
服务器端解决方案(最推荐)
这是最标准的方法,通过服务器在响应头中告知浏览器:允许该请求跨域。
-
CORS (Cross-Origin Resource Sharing)
服务器在 HTTP 响应头中添加Access-Control-Allow-Origin字段。- 允许所有域名:
Access-Control-Allow-Origin: - 允许特定域名:
Access-Control-Allow-Origin: https://www.yourdomain.com - 其他相关头:
Access-Control-Allow-Methods: 允许的请求方法(GET, POST, PUT, DELETE 等)。Access-Control-Allow-Headers: 允许的自定义请求头。Access-Control-Allow-Credentials: 是否允许发送 Cookie(需设为true)。
- 允许所有域名:
-
Nginx 反向代理
在服务器端使用 Nginx 将请求转发到后端接口,使前端请求的域名与后端一致。- 原理:前端 $rightarrow$ Nginx (同源) $rightarrow$ 后端服务器 (服务器间通信无跨域限制)。
客户端/开发环境解决方案
这类方案通常用于开发阶段,无法在生产环境下直接通过 JS 代码解决。
-
开发服务器代理 (Proxy)
在使用 Webpack, Vite 或 Vue-CLI 等工具时,可以配置proxy选项。- 原理:前端代码请求本地开发服务器 $rightarrow$ 开发服务器转发请求到目标服务器 $rightarrow$ 返回结果。
-
特点
:仅在开发环境下有效,部署到生产环境后仍需 Nginx 或 CORS 配置。
JSONP (已过时)
- 原理:利用
<script>标签不受同源策略限制的特性,通过动态创建脚本标签来获取数据。 - 缺点:仅支持 GET 请求,且存在安全风险,现代开发中基本被 CORS 取代。
- 原理:利用
核心机制:简单请求与预检请求
浏览器在处理 CORS 请求时,会根据请求的复杂度将其分为两类:
-
简单请求 (Simple Request)
满足以下条件:- 方法为
GET、POST或HEAD。 - HTTP Header 仅包含基础头(如
Accept,Content-Type且值为application/x-www-form-urlencoded,multipart/form-data,text/plain)。 - 流程:直接发送请求 $rightarrow$ 浏览器检查响应头 $rightarrow$ 允许或拦截。
- 方法为
-
预检请求 (Preflight Request)
如果不满足简单请求条件(例如使用了PUT、DELETE或Content-Type: application/json),浏览器会先发送一个 OPTIONS 请求。- 流程:
- 浏览器发送
OPTIONS请求询问服务器是否允许该操作。 - 服务器返回允许的域名、方法和头信息。
- 浏览器确认无误后,才发送真正的业务请求。
- 浏览器发送
- 流程:
总结对比表
| 方案 | 实现位置 | 适用场景 | 优点 | 缺点 |
|---|---|---|---|---|
| CORS | 后端服务器 | 生产环境/标准 API | 官方标准,安全可控 | 需要后端配合修改代码 |
| Nginx 代理 | 运维/中间层 | 生产环境 | 对前端透明,性能高 | 需要配置服务器软件 |
| Dev Proxy | 前端构建工具 | 本地开发环境 | 配置简单,快速上手 | 仅限开发环境,不能部署 |
| JSONP | 前端 JS | 极旧的浏览器/简单接口 | 兼容性极强 | 仅支持 GET,不安全 |
首发原创文章,作者:世雄 - 原生数据库架构专家,如若转载,请注明出处:https://idctop.com/article/490660.html



