欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

6種SpringBoot解決跨域請求的方法整理

 更新時間:2025年04月03日 08:33:05   作者:風象南  
跨域資源共享是一種標準機制,允許服務器聲明哪些源可以訪問其資源,在SpringBoot應用中,有多種方式可以解決跨域問題,本文主要介紹了6種常見的解決方案,大家可以根據(jù)需求自行選擇

一、跨域問題簡介

在Web開發(fā)中,瀏覽器的同源策略(Same-Origin Policy)是一項重要的安全機制,它限制了一個源(Origin)中加載的文檔或腳本如何與另一個源的資源進行交互。所謂同源,指的是協(xié)議、域名和端口號都相同。當前端應用試圖請求與自身不同源的后端API時,就會遇到跨域問題。

例如,當 http://frontend.com 的前端應用嘗試訪問 http://backend.com/api 的后端服務時,瀏覽器會阻止這種請求,并在控制臺報錯:

Access to XMLHttpRequest at 'http://backend.com/api' from origin 'http://frontend.com' 
has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource.

跨域資源共享(CORS,Cross-Origin Resource Sharing)是一種標準機制,允許服務器聲明哪些源可以訪問其資源。在SpringBoot應用中,有多種方式可以解決跨域問題,下面詳細介紹6種常見的解決方案。

二、方案一:基于@CrossOrigin注解的方法級別控制

這是最簡單直接的方式,通過在Controller類或特定方法上添加@CrossOrigin注解來允許跨域請求。

實現(xiàn)方式

// 在方法級別允許跨域
@RestController
@RequestMapping("/api")
public class UserController {
    
    @CrossOrigin(origins = "http://example.com")
    @GetMapping("/users")
    public List<User> getUsers() {
        // 方法實現(xiàn)
        return userService.findAll();
    }
    
    @GetMapping("/roles")
    public List<Role> getRoles() {
        // 此方法不允許跨域
        return roleService.findAll();
    }
}

// 在類級別允許跨域
@CrossOrigin(origins = {"http://example.com", "http://localhost:3000"})
@RestController
@RequestMapping("/api/products")
public class ProductController {
    
    @GetMapping
    public List<Product> getAllProducts() {
        // 方法實現(xiàn)
        return productService.findAll();
    }
    
    @GetMapping("/{id}")
    public Product getProduct(@PathVariable Long id) {
        // 方法實現(xiàn)
        return productService.findById(id);
    }
}

優(yōu)點

  • 實現(xiàn)簡單直觀
  • 可以精確控制到方法級別
  • 可以針對不同的API設(shè)置不同的CORS規(guī)則

缺點

  • 代碼重復,需要在多個地方添加注解
  • 維護成本高,當CORS策略變更時,需要修改多處代碼
  • 不適合大型項目中統(tǒng)一管理CORS策略

三、方案二:全局CORS配置(WebMvcConfigurer)

通過實現(xiàn)WebMvcConfigurer接口并重寫addCorsMappings方法,可以在全局范圍內(nèi)配置CORS規(guī)則。

實現(xiàn)方式

@Configuration
public class WebConfig implements WebMvcConfigurer {
    
    @Override
    public void addCorsMappings(CorsRegistry registry) {
        registry.addMapping("/api/**")
                .allowedOrigins("http://example.com", "http://localhost:3000")
                .allowedMethods("GET", "POST", "PUT", "DELETE", "OPTIONS")
                .allowedHeaders("*")
                .allowCredentials(true)
                .maxAge(3600); // 1小時內(nèi)不需要再預檢(發(fā)OPTIONS請求)
    }
}

優(yōu)點

  • 可以方便集中管理所有API的CORS配置
  • 配置靈活,可以針對不同的URL模式設(shè)置不同的規(guī)則
  • 代碼簡潔,易于維護

缺點

  • 在某些場景下可能需要與其他安全配置結(jié)合使用

四、方案三:使用CorsFilter

通過定義CorsFilter作為一個Bean,可以在過濾器級別處理跨域請求,這種方式比WebMvcConfigurer的優(yōu)先級更高。

實現(xiàn)方式

@Configuration
public class CorsConfig {
    
    @Bean
    public CorsFilter corsFilter() {
        UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
        CorsConfiguration config = new CorsConfiguration();
        
        // 允許的源
        config.addAllowedOrigin("http://example.com");
        config.addAllowedOrigin("http://localhost:3000");
        
        // 允許的HTTP方法
        config.addAllowedMethod("*");
        
        // 允許的頭信息
        config.addAllowedHeader("*");
        
        // 允許攜帶認證信息(Cookie等)
        config.setAllowCredentials(true);
        
        // 預檢請求的有效期,單位為秒
        config.setMaxAge(3600L);
        
        // 對所有URL應用這些配置
        source.registerCorsConfiguration("/**", config);
        
        return new CorsFilter(source);
    }
}

優(yōu)點

  • 在過濾器級別處理,可以攔截所有請求
  • 優(yōu)先級高于方案二
  • 可以與其他過濾器組合使用
  • 適合在不修改已有Controller的情況下添加CORS支持

缺點

  • 無法精確到方法級別控制
  • 對于復雜的規(guī)則可能不夠靈活

五、方案四:Spring Security中的CORS配置

如果項目使用了Spring Security,需要在Security配置中允許CORS,否則Security可能會攔截跨域請求。

實現(xiàn)方式

@Configuration
@EnableWebSecurity
public class SecurityConfig {
    
    @Bean
    public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
        http
            .cors(Customizer.withDefaults()) // 使用CorsConfigurationSource的默認配置
            .csrf().disable()
            .authorizeHttpRequests(authorize -> authorize
                .requestMatchers("/api/**").authenticated()
                .anyRequest().permitAll()
            )
            .httpBasic(Customizer.withDefaults());
        
        return http.build();
    }
    
    @Bean
    public CorsConfigurationSource corsConfigurationSource() {
        CorsConfiguration configuration = new CorsConfiguration();
        configuration.setAllowedOrigins(Arrays.asList("http://example.com", "http://localhost:3000"));
        configuration.setAllowedMethods(Arrays.asList("GET", "POST", "PUT", "DELETE", "OPTIONS"));
        configuration.setAllowedHeaders(Arrays.asList("Authorization", "Content-Type"));
        configuration.setAllowCredentials(true);
        configuration.setMaxAge(3600L);
        
        UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
        source.registerCorsConfiguration("/**", configuration);
        return source;
    }
}

優(yōu)點

  • 與Spring Security無縫集成
  • 可以結(jié)合認證和授權(quán)規(guī)則一起配置
  • 適合需要安全控制的REST API

缺點

  • 依賴Spring Security
  • 對于不需要安全控制的簡單應用可能略顯復雜

六、方案五:網(wǎng)關(guān)層面解決跨域(Spring Cloud Gateway)

在微服務架構(gòu)中,可以在API網(wǎng)關(guān)層統(tǒng)一處理跨域問題,這樣后端微服務就不需要各自配置CORS了。

實現(xiàn)方式

// Spring Cloud Gateway配置
@Configuration
public class GatewayConfig {
    
    @Bean
    public RouteLocator customRouteLocator(RouteLocatorBuilder builder) {
        return builder.routes()
                .route("user_service_route", r -> r.path("/api/users/**")
                        .uri("lb://user-service"))
                .route("product_service_route", r -> r.path("/api/products/**")
                        .uri("lb://product-service"))
                .build();
    }
    
    @Bean
    public WebFilter corsFilter() {
        return (ServerWebExchange ctx, WebFilterChain chain) -> {
            ServerHttpRequest request = ctx.getRequest();
            if (CorsUtils.isCorsRequest(request)) {
                ServerHttpResponse response = ctx.getResponse();
                HttpHeaders headers = response.getHeaders();
                headers.add("Access-Control-Allow-Origin", "*");
                headers.add("Access-Control-Allow-Methods", "GET, POST, PUT, DELETE, OPTIONS");
                headers.add("Access-Control-Allow-Headers", "Authorization, Content-Type");
                headers.add("Access-Control-Allow-Credentials", "true");
                headers.add("Access-Control-Max-Age", "3600");
                if (request.getMethod() == HttpMethod.OPTIONS) {
                    response.setStatusCode(HttpStatus.OK);
                    return Mono.empty();
                }
            }
            return chain.filter(ctx);
        };
    }
}

優(yōu)點

  • 集中處理所有微服務的跨域問題
  • 后端服務無需關(guān)心跨域配置
  • 便于統(tǒng)一管理和維護
  • 適合微服務架構(gòu)

缺點

  • 依賴Spring Cloud Gateway
  • 配置相對復雜
  • 對于單體應用可能過于重量級

七、方案六:使用代理服務器

通過配置前端開發(fā)服務器代理 (開發(fā)環(huán)境) 或使用Nginx (生產(chǎn)環(huán)境) 等反向代理服務器,可以間接解決跨域問題。這種方式實際上是繞過了瀏覽器的同源策略,而不是直接在后端解決CORS。

前端開發(fā)服務器代理配置(以Vue CLI為例)

// vue.config.js
module.exports = {
  devServer: {
    proxy: {
      '/api': {
        target: 'http://localhost:8080',
        changeOrigin: true,
        pathRewrite: {
          '^/api': '/api'
        }
      }
    }
  }
}

Nginx反向代理配置

server {
    listen 80;
    server_name frontend.example.com;
    
    location / {
        root /usr/share/nginx/html;
        index index.html;
        try_files $uri $uri/ /index.html;
    }
    
    location /api/ {
        proxy_pass http://backend.example.com:8080/api/;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
    }
}

優(yōu)點

  • 完全繞過瀏覽器的同源策略限制
  • 后端無需任何CORS配置

缺點

  • 需要額外的代理配置
  • 增加了系統(tǒng)復雜性
  • 可能引入額外的網(wǎng)絡延遲

八、方案比較與選擇建議

方案實現(xiàn)難度靈活性維護成本適用場景
@CrossOrigin注解小型項目,特定API需要跨域
WebMvcConfigurer大多數(shù)Spring Boot應用
CorsFilter需要優(yōu)先級高的CORS處理
Spring Security有安全需求的應用
網(wǎng)關(guān)層面解決微服務架構(gòu)
代理服務器生產(chǎn)環(huán)境,嚴格的安全要求

九、最佳實踐與注意事項

1. 安全考慮

  • 不要盲目設(shè)置Access-Control-Allow-Origin: *,應該明確指定允許的源
  • 謹慎處理帶有憑證的請求(如Cookie),確保只允許受信任的源
  • 對于敏感操作,考慮使用CSRF令牌進行保護

2. 性能優(yōu)化

  • 合理設(shè)置Access-Control-Max-Age以減少預檢請求
  • 避免在每個請求中都解析和構(gòu)建CORS頭
  • 在網(wǎng)關(guān)層處理CORS可以減輕后端服務的負擔

3. 開發(fā)與調(diào)試

  • 在開發(fā)環(huán)境可以適當放寬CORS限制,但在生產(chǎn)環(huán)境一定要收緊
  • 使用瀏覽器開發(fā)者工具的Network面板調(diào)試CORS問題

十、總結(jié)

跨域請求是前后端分離開發(fā)中不可避免的問題,Spring Boot提供了多種解決方案。從簡單的@CrossOrigin注解到復雜的網(wǎng)關(guān)配置,我們可以根據(jù)項目規(guī)模和需求選擇合適的方案。在實際開發(fā)中,建議綜合考慮安全性、靈活性和維護成本,選擇最適合項目的CORS解決方案。

對于大多數(shù)Spring Boot應用,推薦使用全局CORS配置(WebMvcConfigurer)方案,它提供了良好的平衡性;而對于微服務架構(gòu),則推薦在網(wǎng)關(guān)層統(tǒng)一處理CORS問題,以減少后端服務的配置負擔。

無論選擇哪種方案,都應該遵循"最小權(quán)限原則" ,只允許必要的源訪問必要的資源,確保系統(tǒng)的安全性。

以上就是6種SpringBoot解決跨域請求的方法整理的詳細內(nèi)容,更多關(guān)于SpringBoot解決跨域請求的資料請關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

  • 如何在Maven項目配置pom.xml指定JDK版本和編碼

    如何在Maven項目配置pom.xml指定JDK版本和編碼

    maven是個項目管理工具,如果我們不告訴它要使用什么樣的jdk版本編譯,它就會用maven-compiler-plugin默認的jdk版本來處理,這樣就容易出現(xiàn)版本不匹配的問題,這篇文章主要給大家介紹了關(guān)于如何在Maven項目配置pom.xml指定JDK版本和編碼的相關(guān)資料,需要的朋友可以參考下
    2024-01-01
  • Java字符串相關(guān)類StringBuffer的用法詳解

    Java字符串相關(guān)類StringBuffer的用法詳解

    java.lang包下的StringBuffer類,代表著可變的字符序列,可以用來對字符串內(nèi)容進行增刪改操作。本文將通過示例詳細說說它的用法,感興趣的可以跟隨小編一起學習一下
    2022-10-10
  • Java內(nèi)存區(qū)域管理詳解

    Java內(nèi)存區(qū)域管理詳解

    這篇文章主要介紹了Java內(nèi)存區(qū)域管理詳解,文章通過圍繞主題展開詳細的內(nèi)容介紹,具有一定的參考價值,需要的小伙伴可以參考一下
    2022-09-09
  • 高分面試從Hotspot源碼層面剖析java多態(tài)實現(xiàn)原理

    高分面試從Hotspot源碼層面剖析java多態(tài)實現(xiàn)原理

    這篇文章主要為大家介紹了在面試中從Hotspot源碼層面來剖析java多態(tài)的實現(xiàn)原理,這樣回答薪資隨你開,有需要的朋友可以借鑒參考下,希望大家多多加薪
    2022-01-01
  • Java實現(xiàn)簡單字符生成器代碼例子

    Java實現(xiàn)簡單字符生成器代碼例子

    這篇文章主要介紹了Java實現(xiàn)簡單字符生成器代碼例子,本文直接給出實現(xiàn)代碼,需要的朋友可以參考下
    2015-06-06
  • Java貪心算法超詳細講解

    Java貪心算法超詳細講解

    人之初性本善,但是隨著自身的經(jīng)歷、生活環(huán)境等因素的影響,人逐漸會生出貪嗔癡。實際上不光人有貪念,我們的算法也會有貪念,今天就和大家介紹下一個有貪念的算法模型---貪心算法,看看一個算法是怎么產(chǎn)生貪念的
    2022-05-05
  • Maven添加Tomcat插件實現(xiàn)熱部署代碼實例

    Maven添加Tomcat插件實現(xiàn)熱部署代碼實例

    這篇文章主要介紹了Maven添加Tomcat插件實現(xiàn)熱部署代碼實例,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友可以參考下
    2020-04-04
  • java模擬post請求登錄貓撲示例分享

    java模擬post請求登錄貓撲示例分享

    這篇文章主要介紹了java模擬post請求登錄貓撲的小示例,需要的朋友可以參考下
    2014-02-02
  • java如何讀取文件目錄返回樹形結(jié)構(gòu)

    java如何讀取文件目錄返回樹形結(jié)構(gòu)

    這篇文章主要介紹了java如何讀取文件目錄返回樹形結(jié)構(gòu)問題,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教
    2024-01-01
  • IDEA中Translation使用及問題解決

    IDEA中Translation使用及問題解決

    本文主要介紹了IDEA中Translation使用及問題解決,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2023-06-06

最新評論