跨域处理的核心是解决浏览器的"同源策略"限制,主流方案有以下6种,按推荐优先级和常用场景排序:
1. 后端配置 CORS(跨域资源共享)
这是最推荐、最标准的方案,完全在后端实现,前端无需额外处理。
- 原理:后端在响应头中添加
Access-Control-Allow-Origin
等字段,明确允许指定域名的前端访问。 - 关键响应头:
Access-Control-Allow-Origin: *
(允许所有域名,不推荐生产环境)或https://your-frontend.com
(指定前端域名)Access-Control-Allow-Methods: GET, POST, PUT, DELETE
(允许的请求方法)Access-Control-Allow-Headers: Content-Type
(允许的自定义请求头)
2. 前端使用 Proxy 代理(开发环境常用)
适用于本地开发阶段,通过开发工具(如 Webpack、Vite)配置代理,将跨域请求转发为"同源请求"。
-
原理:前端请求本地代理服务器,代理服务器再转发请求到目标后端(服务器间通信无同源限制)。
-
示例(Vite 配置):
javascript// vite.config.js export default defineConfig({ server: { proxy: { '/api': { // 匹配前端请求路径前缀 target: 'https://target-backend.com', // 目标后端地址 changeOrigin: true, // 伪装请求来源为目标服务器域名 rewrite: (path) => path.replace(/^\/api/, '') // 移除路径前缀(可选) } } } })
3. 后端配置反向代理(生产环境常用)
通过 Nginx、Apache 等服务器,将前端和后端请求统一代理到同一域名下,避免跨域。
-
原理:用户访问
https://your-domain.com
(前端),请求/api
路径时,Nginx 自动转发到后端https://target-backend.com
。 -
示例(Nginx 配置):
nginxserver { listen 80; server_name your-domain.com; # 代理前端静态资源 location / { root /path/to/frontend; index index.html; } # 代理后端接口 location /api { proxy_pass https://target-backend.com; # 转发到后端 proxy_set_header Host $host; # 传递请求头 } }
4. JSONP(仅支持 GET 请求,已过时)
利用 <script>
标签无同源限制的特性,通过回调函数获取跨域数据,仅适用于简单 GET 请求,不推荐新项目使用。
- 原理:前端动态创建
<script>
,请求后端接口并指定回调函数,后端返回该函数包裹的 JSON 数据。
5. 后端设置 document.domain(仅适用于主域名相同的子域名)
当前端域名是 a.example.com
,后端是 b.example.com
时,可通过设置 document.domain = 'example.com'
让两者同源。
- 限制:仅支持主域名相同的场景,且需前后端同时设置。
6. WebSocket(适用于实时通信场景)
WebSocket 协议本身不受同源策略限制,可直接建立跨域实时连接(如聊天、消息推送)。
- 原理:通过
new WebSocket('wss://target-backend.com/ws')
建立连接,后续通信无需处理跨域。
总结 :优先选择 CORS(后端配置) 或 Proxy/反向代理,JSONP、document.domain 等方案仅用于兼容旧系统或特殊场景。
在K8s环境中,Ingress Route(通常指Ingress资源或基于Ingress Controller的路由配置)是处
理跨域的生产级方案,本质是通过K8s的入口流量管理组件,在网关层统一配置CORS规则,无需修改后端服务代码。
核心原理
K8s的Ingress Route本身不直接处理跨域,而是通过Ingress Controller(如Nginx Ingress Controller、Traefik等)实现。其逻辑与"后端反向代理"一致:将前端和后端接口统一通过Ingress暴露在同一域名下,或在Ingress规则中直接配置CORS响应头,从入口层拦截并处理跨域请求。
两种实现方式(以常用的Nginx Ingress Controller为例)
方式1:同一域名下路由转发(彻底避免跨域)
将前端静态资源(如通过ConfigMap挂载或对接对象存储)和后端API服务,通过Ingress配置不同路径的路由,统一暴露在https://your-domain.com
下,前端请求无需跨域。
Ingress YAML示例:
yaml
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: app-ingress
namespace: default
spec:
ingressClassName: nginx # 指定使用Nginx Ingress Controller
rules:
- host: your-domain.com # 统一域名
http:
paths:
# 1. 前端静态资源路由:访问 / 时转发到前端服务
- path: /
pathType: Prefix
backend:
service:
name: frontend-service # 前端服务名
port:
number: 80
# 2. 后端API路由:访问 /api 时转发到后端服务
- path: /api
pathType: Prefix
backend:
service:
name: backend-service # 后端服务名
port:
number: 8080
方式2:跨域名场景下配置CORS响应头
若前端和后端必须使用不同域名(如前端https://fe-domain.com
、后端https://api-domain.com
),可在Ingress注解中直接配置CORS规则,让Ingress Controller在响应中添加跨域头。
Ingress YAML示例:
yaml
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: backend-ingress
namespace: default
annotations:
# 核心CORS注解(Nginx Ingress专属)
nginx.ingress.kubernetes.io/enable-cors: "true" # 开启CORS
nginx.ingress.kubernetes.io/cors-allow-origin: "https://fe-domain.com" # 允许的前端域名
nginx.ingress.kubernetes.io/cors-allow-methods: "GET, POST, PUT, DELETE, OPTIONS" # 允许的请求方法
nginx.ingress.kubernetes.io/cors-allow-headers: "Content-Type, Authorization" # 允许的请求头
nginx.ingress.kubernetes.io/cors-max-age: "86400" # 预检请求缓存时间(24小时)
spec:
ingressClassName: nginx
rules:
- host: api-domain.com # 后端API域名
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: backend-service
port:
number: 8080
关键注意事项
- Ingress Controller依赖 :必须先在K8s集群中部署Ingress Controller(如
nginx-ingress
、traefik
),否则Ingress资源无法生效。不同Controller的CORS配置方式不同(如Traefik用traefik.ingress.kubernetes.io
前缀的注解),需参考对应文档。 - 预检请求处理 :对于
POST
、PUT
等非简单请求,浏览器会先发送OPTIONS
预检请求。Ingress Controller需正确响应OPTIONS
请求,上述注解已自动处理该逻辑。 - 生产环境安全 :避免使用
cors-allow-origin: "*"
(允许所有域名),需明确指定前端域名;同时建议配合HTTPS(通过Ingress配置TLS证书),防止跨域请求被劫持。