Lecture20-跨域与 CORS 专题:前后端联调

文章目录

    [toc]

    单词词性音标含义
    CORSn./kɔːz/跨域资源共享,后端加响应头告知浏览器放行
    originn./ˈɒrɪdʒɪn/源,由协议 + 域名 + 端口组成,任一不同即跨域
    CrossOriginn./krɒs ˈɒrɪdʒɪn/SpringMVC 注解,允许某个接口或控制器跨域
    Access-Control-Allow-Originn./ˈækses kənˈtrəʊl əˈlaʊ ˈɒrɪdʒɪn/响应头,声明允许访问的来源
    preflightn./ˈpriːflaɪt/预检请求(OPTIONS),复杂请求前浏览器先探路
    Networkn./ˈnetwɜːk/开发者工具的 Network 面板,用于验证跨域是否解决
    MVCn./ˌem viː ˈsiː/SpringMVC,后端框架,CORS 配置的落脚点

    Lecture20-跨域与 CORS 专题:前后端联调

    1、本节讲什么

    彻底搞懂"前端调后端接口被浏览器拦截"这件事,并学会在**后端(SpringMVC)**配置 CORS 解决它。

    image-20261007162437675

    2、概念速览

    什么是跨域:前端页面地址和它请求的接口地址,"协议 / 域名 / 端口"任一不同,就叫跨域。浏览器出于安全会拦截。

    什么是 CORS:后端在响应里加"允许哪些来源访问"的响应头,告诉浏览器"这个接口我放行"。

    image-20250730165506683

    关键认知:跨域是浏览器的安全规则,不是后端拒绝你;解决开关在后端,前端做不了主。

    正确 vs 误区:别以为前端能"关掉"跨域——开关在后端响应头;前端能做的是代理(开发期)和排查。

    先说结论(记住这一句)

    跨域是浏览器的安全规则,不是后端拒绝你。解决方法是后端在响应里加允许跨域的响应头(CORS),前端无法靠自己彻底解决,但能配合。

    ① 什么是跨域、为什么报错

    跨域 = 前端页面所在的地址,和它请求的接口地址,"协议 / 域名 / 端口"任一不同就算跨域。

    前端页面地址请求的接口地址是否跨域
    http://localhost:5173http://localhost:5173/api/x否(同源)
    http://localhost:5173http://localhost:8080/api/x是(端口不同)
    http://a.comhttp://b.com/api/x是(域名不同)

    浏览器发现跨域,会先发一个"预检"请求,后端若没在响应里说"我允许这个来源访问",浏览器就把真正的请求拦截,控制台报错类似:

    Access to XMLHttpRequest at 'http://localhost:8080/api/users'
    from origin 'http://localhost:5173' has been blocked by CORS policy
    

    ② 后端怎么解决(SpringMVC 三套写法,任选其一)

    写法一:单个接口加注解 @CrossOrigin

    @RestController
    @RequestMapping("/api/users")
    public class UserController {
        @CrossOrigin   // 允许所有来源访问这个接口
        @GetMapping
        public List<User> list() { ... }
    }
    

    写法二:整个 Controller 加注解

    @CrossOrigin
    @RestController
    @RequestMapping("/api/users")
    public class UserController { ... }
    

    写法三:全局配置类(推荐,一次性管所有接口)

    import org.springframework.context.annotation.Configuration;
    import org.springframework.web.servlet.config.annotation.CorsRegistry;
    import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
    
    @Configuration
    public class CorsConfig implements WebMvcConfigurer {
        @Override
        public void addCorsMappings(CorsRegistry registry) {
            registry.addMapping("/**")            // 所有接口都允许
                    .allowedOrigins("*")          // 允许的来源(生产可限定成你的域名)
                    .allowedMethods("*")          // 允许的方法(GET/POST/PUT/DELETE...)
                    .allowedHeaders("*");         // 允许的请求头
        }
    }
    

    开发期图省事用 *;生产环境建议把 allowedOrigins 改成你的真实前端域名,更安全。

    ③ 前端配合:看 Network 验证是否已解决

    1. 触发一次接口请求。
    2. 打开开发者工具 → Network → 点那条请求 → Headers。
    3. 如果响应头里有 Access-Control-Allow-Origin,说明后端 CORS 配置已生效,问题解决。
    4. 若没有,说明后端没配好,回去检查上面三套写法。

    ④ 前端能做和不能做的

    • 能:通过 Vite 代理(仅开发期,第 19 节)绕过。
    • 能:把报错截图/原文交给后端同学或 AI,明确"是跨域"。
    • 不能:靠前端代码"关掉"跨域。跨域的开关在后端。

    5、常见疑问

    • Q:为什么后端配了 CORS,前端还是报错? A:① 改完代码要重启后端;② allowedOrigins("*") 在带 cookie 的请求上会被浏览器拒绝(需要指定具体来源);③ 代理没配对。按 ③ 的 Network 三步查。
    • Q:allowedOrigins("*") 和指定域名有什么区别? A:* 允许任何网站访问你的接口;指定域名只允许那一个。生产用指定域名更安全。
    • Q:post 请求报跨域,get 不报,为什么? A:浏览器对复杂请求(带 JSON 体、自定义头)会先发"预检",更容易被拦。检查预检请求(Network 里 OPTIONS 开头的那条)是否也被允许。
    • Q:生产环境(部署后)跨域怎么办? A:生产没有 Vite 代理,只能靠后端 CORS(写法三的全局配置),并且 allowedOrigins 填前端真实域名。

    6、规范要点

    • 跨域问题的判断先看 Network,别上来就怀疑代码——90% 是后端 CORS 没配或没重启。
    • 开发期用代理、生产期用 CORS,两条路都掌握。
    • 把"CORS 报错原文 + 是哪个接口 + 期望效果"整理好再去找 AI / 后端,别人才能秒懂(这也是第 39 节的方法)。

    7、本节验证

    • 能判断“协议 / 域名 / 端口任一不同”即跨域 ✅
    • 知道跨域是浏览器规则、开关在后端响应头 ✅
    • 会用 SpringMVC 三套写法之一配置 CORS(@CrossOrigin / 全局配置类) ✅
    • 会打开 Network 看 Access-Control-Allow-Origin 验证是否解决 ✅
    • 知道前端能用开发代理绕、但不能靠自己关掉跨域 ✅
    end