最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

SpringBoot處理跨域請求(CORS)的五種方式

 更新時間:2025年04月20日 08:26:41   作者:北辰alk  
跨域資源共享(CORS)是現(xiàn)代Web開發(fā)中常見的問題,Spring?Boot提供了多種方式來處理CORS請求,下面我將詳細(xì)介紹各種實現(xiàn)方式及其適用場景,需要的朋友可以參考下

一、CORS基礎(chǔ)概念

1. 什么是跨域請求?

當(dāng)瀏覽器從一個域名的網(wǎng)頁去請求另一個域名的資源時,如果域名、端口或協(xié)議不同,就會產(chǎn)生跨域請求。出于安全考慮,瀏覽器默認(rèn)會阻止這類請求。

2. 簡單請求 vs 預(yù)檢請求

類型條件處理方式
簡單請求GET/HEAD/POST方法,且Content-Type為text/plain、multipart/form-data或application/x-www-form-urlencoded直接發(fā)送請求,帶Origin頭
預(yù)檢請求(OPTIONS)不符合簡單請求條件的其他請求先發(fā)送OPTIONS請求,獲得許可后再發(fā)送實際請求

二、Spring Boot處理CORS的5種方式

1. 使用@CrossOrigin注解

適用場景:針對單個控制器或方法級別的CORS配置

@RestController
@RequestMapping("/api")
public class MyController {
    
    // 允許特定源的跨域訪問
    @CrossOrigin(origins = "https://example.com")
    @GetMapping("/resource")
    public ResponseEntity<String> getResource() {
        return ResponseEntity.ok("跨域資源");
    }
    
    // 更詳細(xì)的配置
    @CrossOrigin(origins = {"https://example.com", "https://api.example.com"},
                allowedHeaders = {"Content-Type", "Authorization"},
                methods = {RequestMethod.GET, RequestMethod.POST},
                maxAge = 3600)
    @PostMapping("/save")
    public ResponseEntity<String> saveResource() {
        return ResponseEntity.ok("保存成功");
    }
}

2. 全局CORS配置

適用場景:應(yīng)用級別的統(tǒng)一CORS配置

@Configuration
public class WebConfig implements WebMvcConfigurer {
    
    @Override
    public void addCorsMappings(CorsRegistry registry) {
        registry.addMapping("/api/**")  // 匹配的路徑
                .allowedOrigins("https://example.com", "https://api.example.com") // 允許的源
                .allowedMethods("GET", "POST", "PUT", "DELETE") // 允許的方法
                .allowedHeaders("*") // 允許的請求頭
                .exposedHeaders("Authorization", "Content-Disposition") // 暴露的響應(yīng)頭
                .allowCredentials(true) // 是否允許發(fā)送cookie
                .maxAge(3600); // 預(yù)檢請求緩存時間(秒)
        
        // 可以添加多個配置
        registry.addMapping("/public/**")
                .allowedOrigins("*");
    }
}

3. 使用Filter處理CORS

適用場景:需要更底層控制或與非Spring Web環(huán)境集成

@Configuration
public class CorsFilterConfig {
    
    @Bean
    public FilterRegistrationBean<CorsFilter> corsFilter() {
        UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
        CorsConfiguration config = new CorsConfiguration();
        
        // 配置CORS規(guī)則
        config.setAllowCredentials(true);
        config.addAllowedOrigin("https://example.com");
        config.addAllowedHeader("*");
        config.addAllowedMethod("*");
        config.setMaxAge(3600L);
        
        // 對所有路徑生效
        source.registerCorsConfiguration("/**", config);
        
        FilterRegistrationBean<CorsFilter> bean = 
            new FilterRegistrationBean<>(new CorsFilter(source));
        bean.setOrder(Ordered.HIGHEST_PRECEDENCE); // 設(shè)置最高優(yōu)先級
        
        return bean;
    }
}

4. Spring Security中的CORS配置

適用場景:使用Spring Security的項目

@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
    
    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http.cors().and() // 啟用CORS支持
            .csrf().disable() // 通常CORS和CSRF不能同時使用
            .authorizeRequests()
            .antMatchers("/api/public/**").permitAll()
            .anyRequest().authenticated();
    }
    
    // 提供CORS配置源
    @Bean
    CorsConfigurationSource corsConfigurationSource() {
        CorsConfiguration configuration = new CorsConfiguration();
        configuration.setAllowedOrigins(Arrays.asList("https://example.com"));
        configuration.setAllowedMethods(Arrays.asList("GET", "POST"));
        configuration.setAllowedHeaders(Arrays.asList("*"));
        
        UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
        source.registerCorsConfiguration("/**", configuration);
        
        return source;
    }
}

5. 響應(yīng)頭手動設(shè)置

適用場景:需要動態(tài)控制CORS頭

@RestController
public class DynamicCorsController {
    
    @GetMapping("/dynamic-cors")
    public ResponseEntity<String> dynamicCors(HttpServletRequest request, 
                                           HttpServletResponse response) {
        // 根據(jù)請求動態(tài)設(shè)置CORS頭
        String origin = request.getHeader("Origin");
        if (isAllowedOrigin(origin)) {
            response.setHeader("Access-Control-Allow-Origin", origin);
            response.setHeader("Access-Control-Allow-Credentials", "true");
            response.setHeader("Access-Control-Allow-Methods", "GET, POST");
        }
        
        return ResponseEntity.ok("動態(tài)CORS響應(yīng)");
    }
    
    private boolean isAllowedOrigin(String origin) {
        // 實現(xiàn)你的源驗證邏輯
        return origin != null && origin.endsWith("example.com");
    }
}

三、CORS配置詳解

1. 核心響應(yīng)頭說明

響應(yīng)頭說明
Access-Control-Allow-Origin允許訪問的源,可以是具體域名或*(不推薦使用*,特別是需要憑證時)
Access-Control-Allow-Methods允許的HTTP方法(GET, POST等)
Access-Control-Allow-Headers允許的請求頭
Access-Control-Expose-Headers瀏覽器可以訪問的響應(yīng)頭
Access-Control-Allow-Credentials是否允許發(fā)送cookie(true/false),設(shè)為true時Allow-Origin不能為*
Access-Control-Max-Age預(yù)檢請求結(jié)果的緩存時間(秒)

2. 常見問題解決方案

問題1:預(yù)檢請求(OPTIONS)被攔截

解決方案

  • 確保OPTIONS請求不被安全框架攔截
  • 在Spring Security中配置:
http.cors().and()
    .authorizeRequests()
    .antMatchers(HttpMethod.OPTIONS, "/**").permitAll()

問題2:帶憑證的請求失敗

解決方案

  • 確保allowCredentials(true)和具體的allowedOrigins(不能是*)
  • 前端需要設(shè)置withCredentials: true(如axios)

問題3:特定響應(yīng)頭無法獲取

解決方案

  • 使用exposedHeaders暴露需要的頭:
.exposedHeaders("Custom-Header", "Authorization")

四、最佳實踐建議

  • 生產(chǎn)環(huán)境不要使用通配符*:明確指定允許的源
  • 合理限制HTTP方法:只開放必要的方法(GET/POST等)
  • 考慮使用環(huán)境變量:動態(tài)配置允許的源
@Value("${cors.allowed.origins}")
private String[] allowedOrigins;

// 在配置中使用
.allowedOrigins(allowedOrigins)
  • 結(jié)合安全框架:Spring Security項目使用專門的CORS配置
  • 測試不同場景:簡單請求和預(yù)檢請求都要測試

五、完整配置示例

@Configuration
@EnableWebMvc
public class CorsConfig implements WebMvcConfigurer {
    
    @Value("${app.cors.allowed-origins}")
    private String[] allowedOrigins;
    
    @Override
    public void addCorsMappings(CorsRegistry registry) {
        registry.addMapping("/api/**")
                .allowedOrigins(allowedOrigins)
                .allowedMethods("GET", "POST", "PUT", "PATCH", "DELETE", "OPTIONS")
                .allowedHeaders("*")
                .exposedHeaders("Authorization", "Content-Disposition")
                .allowCredentials(true)
                .maxAge(3600);
                
        registry.addMapping("/public/**")
                .allowedOrigins("*")
                .allowedMethods("GET", "OPTIONS");
    }
    
    // 可選:提供CORS過濾器作為備選
    @Bean
    public FilterRegistrationBean<CorsFilter> corsFilter() {
        UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
        CorsConfiguration config = new CorsConfiguration();
        config.applyPermitDefaultValues();
        config.setAllowCredentials(true);
        config.setAllowedOrigins(Arrays.asList(allowedOrigins));
        source.registerCorsConfiguration("/**", config);
        
        FilterRegistrationBean<CorsFilter> bean = new FilterRegistrationBean<>(new CorsFilter(source));
        bean.setOrder(Ordered.HIGHEST_PRECEDENCE);
        return bean;
    }
}

六、總結(jié)

Spring Boot提供了多種靈活的方式來處理CORS:

  1. 簡單場景:使用@CrossOrigin注解
  2. 統(tǒng)一配置:實現(xiàn)WebMvcConfigureraddCorsMappings方法
  3. 底層控制:配置CorsFilter
  4. 安全項目:結(jié)合Spring Security的cors()配置
  5. 動態(tài)需求:手動設(shè)置響應(yīng)頭

根據(jù)項目需求選擇合適的方式,并遵循安全最佳實踐,可以有效地解決跨域問題,同時保證應(yīng)用的安全性。

以上就是SpringBoot處理跨域請求(CORS)的五種方式的詳細(xì)內(nèi)容,更多關(guān)于SpringBoot處理跨域請求的資料請關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

  • 一個Java中BigDecimal的問題記錄

    一個Java中BigDecimal的問題記錄

    這篇文章主要給大家介紹了關(guān)于Java中一個BigDecimal問題的相關(guān)資料,通過文中介紹的方法可以很方便的解決BigDecimal進行計算的時候不管怎么計算,最后得到的值都沒有變化的問題,需要的朋友可以參考下
    2021-11-11
  • mybatis-plus 查詢時排除字段方法的兩種方法

    mybatis-plus 查詢時排除字段方法的兩種方法

    我們在開發(fā)應(yīng)用時,在某些應(yīng)用場景下查詢有時需要排除某些字段,本文主要介紹了兩種方法,具有一定的參考價值,感興趣的可以了解一下
    2023-09-09
  • Java通過URL獲取公眾號文章生成HTML的方法

    Java通過URL獲取公眾號文章生成HTML的方法

    這篇文章主要介紹了Java通過URL獲取公眾號文章生成HTML的方法,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2019-12-12
  • JDK1.8新特性Stream流式操作的具體使用

    JDK1.8新特性Stream流式操作的具體使用

    這篇文章主要介紹了JDK1.8新特性Stream流式操作的具體使用,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2020-09-09
  • SpringBoot使用@SpringBootTest注解開發(fā)單元測試教程

    SpringBoot使用@SpringBootTest注解開發(fā)單元測試教程

    這篇文章主要介紹了SpringBoot使用@SpringBootTest注解開發(fā)單元測試教程,本文通過詳細(xì)的案例過程來說明如何使用該項技術(shù),需要的朋友可以參考下
    2021-06-06
  • springboot2.x整合tkmapper的示例代碼

    springboot2.x整合tkmapper的示例代碼

    這篇文章主要介紹了springboot2.x整合tkmapper,本文通過實例代碼給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2021-01-01
  • SpringBoot關(guān)閉過程中銷毀DisposableBean解讀

    SpringBoot關(guān)閉過程中銷毀DisposableBean解讀

    這篇文章主要介紹了SpringBoot關(guān)閉過程中銷毀DisposableBean解讀,一個bean的生命周期,指的是 bean 從創(chuàng)建,初始化,一系列使用,銷毀的過程,今天來講講 bean 的初始化和銷毀的方法,需要的朋友可以參考下
    2023-12-12
  • java 基礎(chǔ)教程之多線程詳解及簡單實例

    java 基礎(chǔ)教程之多線程詳解及簡單實例

    這篇文章主要介紹了java 基礎(chǔ)教程之多線程詳解及簡單實例的相關(guān)資料,線程的基本屬性、如何創(chuàng)建線程、線程的狀態(tài)切換以及線程通信,需要的朋友可以參考下
    2017-03-03
  • Spring常用配置及解析類說明

    Spring常用配置及解析類說明

    這篇文章主要介紹了Spring常用配置及解析類說明,涉及Spring常用配置項的方法以及它的解析類等相關(guān)內(nèi)容,具有一定參考價值,需要的朋友可以了解下。
    2017-11-11
  • Java設(shè)計模式之備忘錄模式_動力節(jié)點Java學(xué)院

    Java設(shè)計模式之備忘錄模式_動力節(jié)點Java學(xué)院

    我們在編程的時候,經(jīng)常需要保存對象的中間狀態(tài),當(dāng)需要的時候,可以恢復(fù)到這個狀態(tài)。接下來通過本文給大家分享java設(shè)計模式之備忘錄模式,感興趣的的朋友一起看看吧
    2017-08-08

最新評論

上饶市| 定陶县| 任丘市| 岳西县| 唐河县| 蕲春县| 客服| 微博| 定结县| 土默特左旗| 泾阳县| 临猗县| 玉树县| 张北县| 德令哈市| 岐山县| 马公市| 中宁县| 惠水县| 贡嘎县| 定兴县| 车致| 安岳县| 师宗县| 安乡县| 上饶县| 建湖县| 阳城县| 长沙县| 通道| 社旗县| 克拉玛依市| 灵寿县| 平邑县| 延寿县| 哈巴河县| 都兰县| 阿鲁科尔沁旗| 云林县| 蒲城县| 德安县|