CORS配置文件
可以。结合浏览器侧的 CORS 标准说明和 Spring 官方文档常见配置项基本可以分成两层来看一层是HTTP/CORS 规则本身也就是浏览器认哪些响应头。另一层是Spring 里的配置 API比如allowedOrigins、allowedMethods它们本质上是在生成这些 CORS 响应头。CORS 是一种基于 HTTP 头的机制当请求属于“非简单请求”时浏览器会先发一个OPTIONS预检请求确认服务端是否允许真正的跨域请求。(MDN文档)你现在最关心的可以按下面这些项理解。1. 允许哪些来源allowedOrigins/Access-Control-Allow-Origin这是最核心的一项表示哪些前端来源可以访问后端资源。浏览器看的是响应头Access-Control-Allow-Origin。它可以是某个明确的源例如http://localhost:5173也可以是*表示任意源。MDN 还特别提醒当返回的是具体 origin 而不是*时响应通常应同时带上Vary: Origin这样缓存才不会把某个来源的结果错误复用给别的来源。(MDN文档)在 Spring 里对应的是allowedOrigins(...)Spring 的CorsRegistration和CorsConfiguration都把它定义为“允许浏览器发起跨域请求的来源列表”。(Home)实际作用很好理解只允许你的前端地址访问后端防止随便一个别的站点也能直接拿到接口响应2. 允许哪些 HTTP 方法allowedMethods/Access-Control-Allow-Methods这项表示跨域请求允许使用哪些方法例如GET、POST、PUT、DELETE、OPTIONS。对预检请求来说浏览器会先问“我等下想用某种方法发请求行不行” 服务端就要通过Access-Control-Allow-Methods告诉浏览器哪些方法被允许。MDN 里明确列出如果预检阶段在这个头里找不到目标方法浏览器就会判定失败。(MDN文档)所以你前面遇到的情况就很典型配置里没放OPTIONS预检直接被拦浏览器报 CORS 错。Spring 文档也说明它支持配置允许的方法列表。(Home)3. 允许哪些请求头allowedHeaders/Access-Control-Allow-Headers这项表示前端真实请求里允许带哪些自定义请求头。常见的就是AuthorizationContent-TypeX-Requested-With对于预检请求浏览器会把自己准备发送的头放在Access-Control-Request-Headers中如果服务端没有在Access-Control-Allow-Headers里允许这些头浏览器就不会继续发真实请求。MDN 明确说了当预检请求带有Access-Control-Request-Headers时这个响应头是必需的。(MDN文档)这也是很多“登录成功但带 token 的接口失败”的另一常见根因不是方法没放行而是Authorization头没放行。Spring 中对应allowedHeaders(...)。(Home)4. 是否允许携带凭证allowCredentials/Access-Control-Allow-Credentials这项表示浏览器是否可以在跨域请求中携带凭证例如CookieHTTP 认证信息某些带凭据的请求上下文MDN 说明得很清楚Access-Control-Allow-Credentials的有效值只有true如果需要凭证但服务端没返回这个头浏览器会报网络错误。它还强调了一个很重要的限制当允许凭证时Access-Control-Allow-Origin不能用*。(MDN文档)在 Spring 里对应allowCredentials(...)。这项经常用于前后端分离但仍用 Cookie 会话需要跨域发送认证信息的场景如果你们前端是用Authorization: Bearer xxx这通常更多和allowedHeaders、预检放行相关如果是 Cookie 登录态则allowCredentials(true)更关键。Spring 文档也提到像allowCredentials和maxAge这类单值属性局部配置会覆盖全局配置。(Home)5. 预检结果缓存多久maxAge/Access-Control-Max-Age这项表示浏览器可以把预检结果缓存多长时间单位通常是秒。意思是在缓存有效期内浏览器不必每次都先发一遍OPTIONS性能会更好。Spring 官方文档把它作为 CORS 常见配置项之一CorsConfiguration也明确提供了maxAge相关设置。(Home)它的作用主要是减少预检开销尤其是接口调用频繁的时候。6. 允许前端读取哪些响应头exposedHeaders/Access-Control-Expose-Headers默认情况下浏览器并不会把所有响应头都暴露给前端 JS。如果你希望前端通过fetch或axios读取某些响应头比如Content-DispositionX-Trace-IdX-Total-Count就要通过Access-Control-Expose-Headers显式暴露。Spring 里对应exposedHeaders(...)Spring 官方把它列为标准 CORS 配置项之一。(Home)它的作用是后端虽然返回了头但前端 JS 默认未必能读到暴露后才能读。7. 允许的来源模式allowedOriginPatterns这是 Spring 里的一个增强项不是浏览器 CORS 头的名字而是 Spring 为了方便配置提供的模式匹配能力。CorsRegistration官方 API 里明确说明了allowedOriginPatterns(...)并指出如果同时设置了allowedOriginPatterns它会优先生效。(Home)它适合这种场景本地开发多个端口一批子域名要放行不想一个个把 origin 写死和allowedOrigins的区别是allowedOrigins更适合精确列举allowedOriginPatterns更适合模式匹配8. 全局配置与局部配置Spring 官方文档说明CORS 可以做全局配置也可以做局部配置一般规则是多数属性会做叠加但像allowCredentials、maxAge这类单值属性局部会覆盖全局。(Home)这在实际项目里很重要因为经常会出现全局允许一组前端域名某个接口单独再收紧或放宽规则9. 一个常见误区只配 methods不配 headers你前面的案例就是最容易踩坑的组合之一。很多人会写.allowedMethods(GET,POST,PUT,DELETE)但如果真实请求带Authorization或特殊Content-Type那只配 methods 还不够还要确保OPTIONS放行Authorization在allowedHeaders里被允许如果走 Cookie会话类场景还要考虑allowCredentials。这些都是浏览器 CORS 机制和 Spring 官方配置模型共同要求的。(MDN文档)一个实战层面的理解框架可以把常见配置项记成这 6 个问题谁能来allowedOrigins/allowedOriginPatterns能用什么方法来allowedMethods请求里能带什么头allowedHeaders能不能带凭证allowCredentials前端能读哪些响应头exposedHeaders预检结果缓存多久maxAge一个常见的 Spring 配置示意只作为理解示意registry.addMapping(/**).allowedOrigins(http://localhost:5173).allowedMethods(GET,POST,PUT,DELETE,OPTIONS).allowedHeaders(Authorization,Content-Type).exposedHeaders(Content-Disposition).allowCredentials(true).maxAge(3600);这段的语义就是允许http://localhost:5173调你允许这些方法包括预检用的OPTIONS允许前端带Authorization、Content-Type允许前端读取Content-Disposition允许携带凭证预检结果缓存 1 小时