2025新时代 | 分析并解决企业跨域问题

本篇文章仅代表 个人观点

目录

问题分析

同源策略

满足条件

项目架构

案例分析

代码分享

前端

后端

后端配置解决跨域

注解方式

全局配置

现代企业实践

Nginx解决跨域

跨域常见问题集锦

安全建议


问题分析

同源策略

跨域问题的核心来源于浏览器的 同源策略(Same-Origin Policy) ,这是浏览器的一种安全机制,限制不同源的脚本或资源进行交互。在 前后端分离架构 的现代项目中,前端(如 React、Vue)和后端(如 Spring Boot、Node.js)通常部署在不同域名或端口下进行请求通信就会遇到问题。

满足条件

总之必须就得满足三个条件一致,就不会触发同源策略

  1. 协议 (http | https | file ....)
  2. IP (ipv4 | ipv6 | 域名 | 内网穿透 ....)
  3. 端口 (80 | 8080 | 8090 .....)

项目架构

案例分析

后面,我会出一期"关于多种请求方式"这个话题来讲!

项目架构:前后端分离

前端项目:live-server 搭建的临时静态页面,端口 8090

请求方式:fetch(替代了ajax)

后端项目:springboot 构建的临时控制层,端口 8080

前端获取用户输入的值后,JS 原生API工具 请求给后端 ,后端处理数据后,进行返回 ,但是因为端口号不一致,所以就被浏览器拦截了请求,

代码分享

前端

html 复制代码
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <script>
        function go() {
            const number = document.getElementById('name').value;
            fetch("http://127.0.0.1:8080/hello?a="+number)
            .then(response => response.text())
            .then(data => console.log(data));
        }
    </script>
</head>
<body>
    <input type="text" name="a" id="name" placeholder="Number a">
    <button type="button" onclick="go()">go</button>
</body>
</html>

后端

|---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| 后端的springboot构建方式 |
| 超简易SpringBoot工程构建与部署 ( 图解 - 零基础专属 ) <---这个是您想要的项目构建方式 |
| Springboot | 零基础快速搭建JWT简单登录案例(一) |
| SpringBoot构建项目后出现Connect timed out/Read timed out |
| 基于SpringBoot构造超简易QQ邮件服务发送(分离-图解-新手) |

java 复制代码
//Temp.java
package com.chen.www.demos;//这是包名,到时候智能提示会改掉的

import org.springframework.web.bind.annotation.CrossOrigin;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
//@CrossOrigin(origins = "*") 这是后续讲到的跨域注解
public class Temp {
    @GetMapping("/hello")
    public int hello(int a) {
        System.out.println("Hello !"+a);
        return a;
    }
}

后端配置解决跨域

注解方式

通过 @CrossOrigin 注解直接在 Controller 或方法上声明允许跨域

java 复制代码
@RestController
@CrossOrigin(
    origins = "https:/127.0.0.1:8090",  // 这里是允许谁通过
    allowedHeaders = "*",                 // 允许的请求头
    methods = {RequestMethod.GET, RequestMethod.POST} // 允许的 HTTP 方法
)
public class ApiController {
    // ...
}

全局配置

在配置类中定义全局跨域规则,适合微服务架构下的统一管理(Spring Security 或 WebMvcConfigurer)

java 复制代码
@Configuration
public class CorsConfig implements WebMvcConfigurer {
    @Override
    public void addCorsMappings(CorsRegistry registry) {
        registry.addMapping("/**")
                .allowedOrigins("https:/127.0.0.1:8090")  // 这里是允许谁通过
                .allowedMethods("*")
                .allowCredentials(true)
                .maxAge(3600);
    }
}

现代企业实践

  • API 网关统一处理 :在微服务架构中,通过 Kong、Spring Cloud Gateway 等网关组件集中配置跨域策略。

  • 云服务集成:使用 AWS API Gateway、Azure API Management 等云服务自动配置 CORS 规则。

Nginx解决跨域

|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| 安装教程 |
| Linux | 零基础Ubuntu安装部署 Nginx服务 |

通过 Nginx 将前端和后端请求代理到同一域名下,绕过浏览器同源策略:

java 复制代码
server {
    listen 8090;
    server_name https:/127.0.0.1:8090; # 这里是前端服务器

    location /api {
        proxy_pass https:/127.0.0.1:8080;  # 后端服务地址
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;

        # 添加 CORS 响应头
        add_header 'Access-Control-Allow-Origin' 'https:/127.0.0.1:8090';
        add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS';
        add_header 'Access-Control-Allow-Headers' 'Content-Type, Authorization';
    }

    # 前端静态资源
    location / {
        root /usr/share/nginx/html;
        index index.html;
    }
}

跨域常见问题集锦

(认知 → 入门 → 新手 → 老手 → 企业实践 → 大佬)

Q0: 被拦截前,请求能修改数据吗?

A:0 是的,只是返回响应时,被浏览器拦截了。


Q1:为什么本地开发时前端访问后端接口会报跨域错误?
A1 :本地前端(如 localhost:3000)和后端(如 localhost:8080)端口不同,属于跨域。浏览器的同源策略会拦截 AJAX 请求的响应。
解决

  • 后端配置 @CrossOrigin(Spring Boot)或 CORS 头(Node.js)。

  • 前端开发环境代理(Webpack/Vite)。


Q2:后端已经配置了 @CrossOrigin,为什么还是跨域失败?
A2:常见原因:

  1. 未启用 allowCredentials :若请求带 Cookie/JWT,需配置 allowCredentials=true,且 allowedOrigins 不能为 *

  2. HTTP 方法或 Header 未允许 :如 PUTDELETE 或自定义 Header 需显式声明。

  3. Spring Security 拦截:需在 Security 配置中放行跨域。


Q3:JSONP 能解决跨域吗?为什么不推荐使用?
A3 :JSONP 通过 <script> 标签加载跨域脚本,仅支持 GET 请求。
缺点

  • 安全性差(易受 XSS 攻击)。

  • 无法处理错误和异步场景。

  • 已被 CORS 取代,现代项目不建议使用。


Q4:预检请求(Preflight)对性能有什么影响?如何优化?
A4

  • 影响:非简单请求(如带自定义 Header 的 POST)会先发 OPTIONS 请求,增加一次 RTT(往返延迟)。

  • 优化

    1. 后端设置 Access-Control-Max-Age 缓存预检结果(如 3600 秒)。

    2. 减少非必要自定义 Header。

    3. 合并请求,减少预检次数。


Q5:跨域请求携带 Cookie/JWT 时需要注意什么?
A5

  • 前端

    javascript 复制代码
    fetch(url, { 
      credentials: 'include' // 允许发送 Cookie
    });
  • 后端

    • 配置 allowCredentials=true

    • allowedOrigins 必须为具体域名(不能为 *)。

    • 设置 Access-Control-Expose-Headers: Authorization 以暴露 Token。


Q6:被拦截前,请求能修改数据吗?
A6

  • 简单请求(如 GET/POST):请求会到达服务器并执行操作(如插入数据库),但响应被浏览器拦截。

  • 预检请求(如 PUT/DELETE):OPTIONS 预检失败时,实际请求不会发送,数据不会被修改。


Q7:微服务架构下如何统一管理跨域配置?
A7

  • API 网关:通过 Kong、Spring Cloud Gateway 等网关集中配置 CORS 策略,避免每个服务重复配置。

  • 云服务:AWS API Gateway、Azure API Management 支持一键开启 CORS。

  • Kubernetes Ingress:在 Ingress 层添加 CORS 注解。

    bash 复制代码
    nginx.ingress.kubernetes.io/enable-cors: "true"
    nginx.ingress.kubernetes.io/cors-allow-origin: "https://web.example.com"

Q8:生产环境跨域配置与开发环境有何不同?
A8

  • 开发环境

    • 使用前端代理(如 Vite Proxy)或后端允许所有源(allowedOrigins: "*")。
  • 生产环境

    • 严格限制 allowedOrigins 为可信域名(如 https://web.example.com)。

    • 启用 HTTPS,配置 HSTS 防止协议降级攻击。

    • 通过 WAF(Web 应用防火墙)过滤恶意跨域请求。


Q9:如何监控和排查跨域问题?
A9

  1. 浏览器日志:通过开发者工具的 Console 和 Network 查看 CORS 错误和请求详情。

  2. 后端日志:检查 OPTIONS 和实际请求是否到达服务。

  3. APM 工具:使用 Datadog、New Relic 跟踪跨域请求链路。

  4. 安全扫描:使用 OWASP ZAP 检测不安全的 CORS 配置。


Q10:跨域场景下文件上传(如 Multipart)会触发预检吗?
A10

  • 会触发预检 :因为 Content-Type: multipart/form-data 属于非简单请求。

  • 优化方案

    1. 后端预检配置允许 Content-Type

    2. 分片上传改为简单请求(如 Base64 编码)。

安全建议

  • 精细化控制 :避免使用 allowedOrigins: "*",明确指定可信域名,严格限制来源。

  • JWT 鉴权 :跨域请求中通过 Authorization Header 传递 Token。

  • 性能优化:缓存预检请求,合并非简单操作。

  • 监控与日志:通过 APM 工具(如 Datadog、SkyWalking)追踪跨域请求异常。

  • 监控兜底:生产环境需监控跨域异常,防止配置错误导致服务不可用。

  • 架构选择

    • 小型项目:后端直接配置 CORS。

    • 中大型项目:通过网关或反向代理(Nginx)统一管理。


往期内容

|--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| 基于SpringBoot构造超简易QQ邮件服务发送(分离-图解-新手)-CSDN博客 |
| 基于SpringBoot构造超简易QQ邮件服务发送 第二版-CSDN博客 |
| SpringBoo+Vue简单开发"任务管理系统"学生版(GTD+OKR简易测试版)_springboot + vue 控制任务流程的组件 |
| 热部署 | 解决SrpingBoot编译失败跟重复手动编译问题(新手图解)_springboot重新编译-CSDN博客 |

感谢阅读 | 更多内容尽在公棕号 wmcode

相关推荐
vipbic2 分钟前
中后台越做越乱后,我用插件化把它救回来了
前端·vue.js
Hyyy8 分钟前
Computer Use 适合做什么,不适合做什么——一次真实使用后的思考
前端
小和尚同志34 分钟前
前端 AI 单元测试思考与落地
前端·人工智能·aigc
invicinble2 小时前
c端系统,其实更像一个信息展示平台
前端
李姆斯3 小时前
管理是否可以被完全量化
前端·产品经理·团队管理
戮漠summer3 小时前
Missing Semester 计算机教育中缺失的一课 Lecture 01 Shell
开发语言·后端·scala
名字还没想好☜3 小时前
Next.js 中间件实战:鉴权、重定向与 A/B 分流
开发语言·前端·javascript·中间件·react·next.js
广州灵眸科技有限公司3 小时前
瑞芯微RV1126B开发板(EASY-EAI-PI2) INI文件操作
java·前端·javascript·网络·人工智能
江华森4 小时前
Web 开发基础:HTTP 与 REST
前端·网络协议·http
IT_陈寒5 小时前
Redis的KEYS命令把我搞崩溃了,改用SCAN才活过来
前端·人工智能·后端