早期常用 JSONP 解決跨域,但僅支援 GET、安全性差、錯誤處理困難。現代 Web 開發標準採用 CORS (Cross-Origin Resource Sharing),透過 HTTP 標頭讓瀏覽器允許跨源請求,支援所有 HTTP 方法、更安全、易除錯。
@Component
@Order(Ordered.HIGHEST_PRECEDENCE) // 確保最先攔截
public class CorsFilter implements Filter {
@Override
public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain)
throws IOException, ServletException {
HttpServletResponse response = (HttpServletResponse) res;
HttpServletRequest request = (HttpServletRequest) req;
// 1. 允許跨域來源 (* 表示全部,生產建議指定具體域名)
response.setHeader("Access-Control-Allow-Origin", "*");
// 2. 允許的 HTTP 方法
response.setHeader("Access-Control-Allow-Methods", "GET, POST, PUT, DELETE, OPTIONS, PATCH");
// 3. 允許的請求標頭 (含自定義 Token 標頭)
response.setHeader("Access-Control-Allow-Headers", "Content-Type, Authorization, X-Requested-With, X-Custom-Header, HaiYi-Access-Token");
// 4. 允許攜帶 Cookie (需前端 withCredentials=true,且 Origin 不能為 *)
// response.setHeader("Access-Control-Allow-Credentials", "true");
// 5. 預檢請求快取時間 (秒)
response.setHeader("Access-Control-Max-Age", "3600");
// 6. 處理預檢請求
if ("OPTIONS".equalsIgnoreCase(request.getMethod())) {
response.setStatus(HttpServletResponse.SC_NO_CONTENT);
return; // 直接返回,不進入 Controller
}
chain.doFilter(req, res);
}
// init/destroy 可留空
}
加上 @Component 即可自動註冊。若需精確控制路徑順序,可用 FilterRegistrationBean:
@Bean
public FilterRegistrationBean corsFilterRegistration() {
FilterRegistrationBean bean = new FilterRegistrationBean<>(new CorsFilter());
bean.addUrlPatterns("/*");
bean.setOrder(Ordered.HIGHEST_PRECEDENCE);
return bean;
}
無需寫 Filter,僅需實作介面:
@Configuration
@EnableWebMvc
public class WebConfig implements WebMvcConfigurer {
@Override
public void addCorsMappings(CorsRegistry registry) {
registry.addMapping("/**")
.allowedOrigins("*") // 生產環境請指定具體域名
.allowedMethods("GET", "POST", "PUT", "DELETE", "OPTIONS", "PATCH")
.allowedHeaders("*")
.allowCredentials(false) // true 時 origins 不能為 *
.maxAge(3600);
}
}
| 場景 | 配置要點 |
|---|---|
| 前端需攜帶 Cookie/Session | 後端 allowCredentials(true) + 前端 withCredentials: true + Origins 必須指定具體域名,不能為 * |
| 複雜請求觸發預檢 | 確保 OPTIONS 正確返回 204/200 且含 CORS 標頭,Filter 中需提前返回 |
| Spring Security 環境 | 需在 HttpSecurity 中配置 .cors(),並確保 CorsFilter/Configurer 在 Security Filter Chain 之前 |
| Gateway/Zuul 微服務網關 | 在網關層統一配置 CORS,下游服務無需重複配置 |
CORS 是現代 Web 跨域的標準解法。Spring Boot 環境下,推薦使用 WebMvcConfigurer 統一聲明式配置,簡潔且集中管理。理解預檢機制、憑證模式與 Spring Security 整合細節,能避開 90% 的跨域坑。