静态资源映射与 CORS 跨域配置

前后端分离时代,CSS/JS/图片、以及浏览器的跨域访问限制都是接口开发绕不开的配置项。这一章讲 Spring MVC 如何托管静态资源、如何放开 CORS。

静态资源映射

把 classpath 或文件系统的目录暴露成 URL 路径,用 WebMvcConfigurer.addResourceHandlers:

@Configuration
@EnableWebMvc
public class WebConfig implements WebMvcConfigurer {
    @Override
    public void addResourceHandlers(ResourceHandlerRegistry registry) {
        registry.addResourceHandler("/static/**")               // URL 前缀
                .addResourceLocations("classpath:/static/")     // 物理位置(以 / 结尾)
                .setCachePeriod(3600);                          // 缓存秒数
        // 也支持 file:/data/upload/ 指向服务器磁盘目录
    }
}
// 访问 /static/app.js → classpath:/static/app.js
  • addResourceLocations 必须以 / 结尾,可写多个位置按顺序找。
  • 静态资源处理器还支持 Last-Modified/ETag 校验、资源链(ResourceChain)与版本号策略(内容指纹缓存),细节以官方文档为准。
  • 当 DispatcherServlet 映射 / 时,找不到映射的路径可委托容器默认 Servlet:
@Override
public void configureDefaultServletHandling(DefaultServletHandlerConfigurer configurer) {
    configurer.enable();
}

注意:控制器 @GetMapping("/static/**") 之类若与资源映射冲突,按 HandlerMapping 顺序,注解映射优先——想让两者各管一段,路径设计上就分开前缀。

CORS 是什么

浏览器同源策略:页面 https://example.com 里的 JS 默认不能跨源调用 https://api.example.com 的接口。CORS(跨源资源共享)通过响应头 Access-Control-Allow-Origin 等告诉浏览器「这个源允许访问」。

  • 简单请求:直接带上 Origin 发请求,看响应头放不放行。
  • 预检请求:非简单请求(自定义头、PUT/DELETE、application/json 等)先发 OPTIONS 预检,通过后才发真实请求。

注解式:@CrossOrigin

最小粒度,标在方法或类上:

@RestController
@CrossOrigin(origins = "https://example.com") // 类级别:整个控制器放行该源
public class UserApi {
    @GetMapping("/api/users/{id}")
    @CrossOrigin(origins = "*", maxAge = 3600) // 方法级别覆盖类级别
    public User getUser(@PathVariable Long id) { ... }
}

全局配置:addCorsMappings

集中管理所有接口的跨域策略:

@Override
public void addCorsMappings(CorsRegistry registry) {
    registry.addMapping("/api/**")
            .allowedOrigins("https://example.com")   // 精确允许的源
            .allowedMethods("GET", "POST", "PUT", "DELETE", "OPTIONS")
            .allowedHeaders("*")
            .allowCredentials(true)                  // 是否允许携带 Cookie
            .maxAge(3600);                           // 预检结果缓存秒数
}
  • allowedOrigins("") 与 allowCredentials(true) 不能同时使用(通配配凭证不安全);Spring 5.3+ 提供 allowedOriginPatterns("") 来表达「任意源 + 携带凭证」,具体限制以官方文档为准。
  • allowCredentials(true) 时浏览器要求 Access-Control-Allow-Origin 返回具体源而非 *。
  • 不用注解时,预检 OPTIONS 由 MVC 内部 CORS 拦截逻辑处理;若请求没命中任何处理器(例如被安全框架挡在前面),可改用 org.springframework.web.filter.CorsFilter 在过滤器层处理,方案对比以官方文档为准。

常见坑

  • 只配了接口 CORS 忘了静态资源/文件下载接口 → 分开配多段 mapping。
  • 改了 allowedOrigins 没生效 → 检查是否走了缓存(maxAge)或代理层丢头。
  • 出现「CORS 头缺失」但明明配了 → 多半是异常被全局处理后响应头被覆盖,或 OPTIONS 被过滤器/鉴权拦截。

静态资源让 URL 直达文件,CORS 让跨源调用有章可循。资源映射记住「URL 前缀 → 物理位置」成对出现,跨域记住「源 + 方法 + 头 + 凭证」四要素齐配,开发环境与生产环境各配一份。

笔记加载中…