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

Spring Boot CORS 配置方法允許跨域請求的最佳實踐方案

 更新時間:2024年11月20日 11:37:22   作者:baby bear 竟陵  
跨域請求在現(xiàn)代Web開發(fā)中非常重要,特別是在涉及多個前端和后端服務時,本文詳細介紹了跨域請求的背景、重要性以及如何解決跨域問題,通過SpringBoot框架的CORS配置,可以有效地處理跨域請求,確保數(shù)據(jù)傳輸?shù)陌踩院陀脩趔w驗,感興趣的朋友跟隨小編一起看看吧

跨域請求的背景和重要性

在現(xiàn)代 Web 開發(fā)中,跨域請求是一個常見且重要的概念。隨著互聯(lián)網(wǎng)應用的日益復雜,尤其是在涉及多個前端和后端服務的情況下,跨域問題經(jīng)常會對應用的功能和用戶體驗造成影響。

背景

開發(fā)項目時,遇到一個需求,當時項目配套的線下商鋪已由物業(yè)交付給我司運營,運營團隊需要招商引資,經(jīng)過公司考慮決定開發(fā)一個公眾號交給運營團隊,以便客戶能夠在線選擇商鋪。公眾號內(nèi)嵌一個H5頁面,做到用戶點擊平面圖中單元格(每一個商鋪號就是一個單元格)優(yōu)先鎖定商鋪,由于商鋪分布在多個區(qū)域,UI繪圖也需要時間,再加需求緊迫,項目必須在三天內(nèi)上線。前端團隊采用了 Canvas 技術(shù),讓用戶能夠直觀地選擇商鋪單元格,并填寫提交個人資料。開發(fā)過程中,前后端進行了接口聯(lián)調(diào),在測試環(huán)境中沒有明顯的問題。然而,當項目部署到微信公眾號后,出現(xiàn)了跨域請求問題,直接是空白頁面。

當時,前端因為配置代理的進度緩慢,跨域配置的解決方案轉(zhuǎn)到了后端。這一問題突顯了跨域請求在 Web 開發(fā)中的重要性,特別是在需要與多個服務進行交互時。

跨域請求的重要性

  • 安全性:瀏覽器的同源政策旨在保護用戶,防止惡意網(wǎng)站竊取信息??缬蛘埱笮枰?jīng)過嚴格的檢查和配置,以確保數(shù)據(jù)傳輸?shù)陌踩浴?/li>
  • 用戶體驗:跨域請求的限制可能會導致用戶在操作過程中遇到障礙,影響應用的流暢性和可用性。在我們的項目中,如果不及時解決跨域問題,將會直接影響客戶體驗和業(yè)務進展。
  • 業(yè)務需求:在某些情況下,業(yè)務需求可能需要不同來源的資源交互。例如,在我們開發(fā)的微信公眾號中,需要與后端服務進行數(shù)據(jù)交互,以完成用戶的選擇和定金繳納等操作。
  • 快速迭代:隨著項目的推進,及時處理跨域問題是確保項目快速上線的重要環(huán)節(jié)。在短時間內(nèi)解決跨域配置,能夠為后續(xù)的功能擴展和業(yè)務發(fā)展打下良好的基礎(chǔ)。

什么是跨域 

跨域是指在 Web 應用中,由于瀏覽器的同源政策(Same-Origin Policy),不同源的網(wǎng)頁之間進行交互時所遇到的限制。源的定義包括三個部分:協(xié)議(如 httphttps)、域名(如 example.com)和端口(如 80443)。只有當這三者都相同的時候,兩個 URL 被認為是同源的。

為什么有同源政策?

通俗來說,瀏覽器廠商開發(fā)出來的瀏覽器都是有做安全限制的,當你打開某個網(wǎng)站時,瀏覽器就已經(jīng)將請求標頭中的origin屬性改成了當前網(wǎng)站的域名。例如我訪問bilibili,會是這樣的一個origin,你在當前頁面中做以下幾種操作,均會出現(xiàn)跨域:

跨域的情形

1,http://www.bilibili.com(假設(shè)存在)

2,https://www.bilibili.com:8086(假設(shè)存在)

3,http://admin.www.bilibili.com(假設(shè)存在)

跨域原因解釋

情況1跨域的原因是scheme(標識特定協(xié)議或資源類型的字符串)變了

情況2 跨域的原因是port(端口號)變了

情況3跨域的原因是host(域名,admin.www.bilibili.com是域名)變了

如何證明上述情況就是跨域?

跨不跨域框架說了算,來看看Springboot框架是如何認定為跨域的,先附上截圖,然后給源碼解釋

處理請求相關(guān)的參數(shù),并通過比較來判斷是否跨域的源碼

package org.springframework.web.cors;
public abstract class CorsUtils {
    public CorsUtils() {
    }
//方法名就直接體現(xiàn)了方法的作用,判斷是否是跨域請求
public static boolean isCorsRequest(HttpServletRequest request) {
        String origin = request.getHeader("Origin");
        if (origin == null) {
            return false;
        } else {
            UriComponents originUrl = UriComponentsBuilder.fromOriginHeader(origin).build();
            String scheme = request.getScheme();
            String host = request.getServerName();
            int port = request.getServerPort();
//上面的代碼是從請求體中獲取協(xié)議,域名,端口的value值,拿到這些值就是為了和Origin作比較
//通過截圖也能看到Origin包含了scheme,host,port,他們分別是https,www.bilibili.com,443
            return !ObjectUtils.nullSafeEquals(scheme, originUrl.getScheme())
 || !ObjectUtils.nullSafeEquals(host, originUrl.getHost())
 || getPort(scheme, port) != getPort(originUrl.getScheme(), originUrl.getPort());
        }
    }
}

源碼中不難看出來,在經(jīng)過一番處理之后,會通過客戶端傳遞的Origin中的信息和接口服務資源做協(xié)議,端口,域名的比對,只要有一處不一樣那就是跨域,框架會告知瀏覽器跨域,具體的比對過程并不難,我已經(jīng)貼出來了包名和類名,鼓勵朋友們自己動手。

為什么是這樣,而不是那樣

既然服務器有處理請求,為什么你在瀏覽器上看不到響應回來的HTTP狀態(tài)碼,服務器應該要給客戶端返回個狀態(tài)碼,取而代之的卻是顯示:此請求沒有發(fā)起程序請求或者類似的其他提示,這都要歸功于預檢請求,也是瀏覽器廠商默認遵循的一個標準規(guī)范,屬于 CORS(跨源資源共享)機制的一部分。

跨域提示截圖

或者

預檢請求

預檢請求(Preflight Request)是 CORS(跨源資源共享)機制中的一個重要概念,用于在發(fā)送復雜的跨域請求之前,先向服務器發(fā)送一個 HTTP OPTIONS 請求,以確認服務器是否允許實際的請求。預檢請求的目的是為了增強安全性,確??蛻舳嗽诎l(fā)送敏感數(shù)據(jù)時得到服務器的許可。

何時觸發(fā)預檢請求

預檢請求通常在以下情況下觸發(fā):

1.復雜請求

  • 當使用的 HTTP 方法不是簡單請求中的 GET 或 POST(如 PUT、DELETE)。
  • 當請求中包含自定義頭部(例如,X-Custom-Header)。
  • Content-Type 的值不是簡單請求允許的類型(如 application/x-www-form-urlencoded、multipart/form-datatext/plain)。

2.服務器端的 CORS 配置

  • 只有在服務器配置了 CORS,并明確允許來自特定源的請求時,預檢請求才會返回成功。

預檢請求關(guān)服務器什么事情 

完全不瞎說,有沒有預檢請求,依舊是springboot框架說了算,先附上原圖,在附上部分源碼

當我從知乎頁面上請求我本機的服務接口時

服務器處理預檢請求

首先服務器確實收到了該次請求,截圖如下:

57255edf057d457f96a065319e298236.png

處理預檢請求的截圖:

1600abebf4584464ab5b8cbda32ffcb2.png

OPTIONS請求就是預檢請求的請求方式,這里解釋不了為什么,只能回答這就是規(guī)范

處理預檢請求的源碼:

 public static boolean isPreFlightRequest(HttpServletRequest request) {
        //先判斷是不是OPTIONS請求,若是,則表示是預檢請求
        return HttpMethod.OPTIONS.matches(request.getMethod())
        //預檢請求時,http請求頭一定要給Origin
         && request.getHeader("Origin") != null 
        //預檢請求時,會給定名為Access-Control-Request-Method的請求頭
         && request.getHeader("Access-Control-Request-Method") != null;
    }

服務器如何處理跨域呢,允許還是不允許? 

允許還是不允許,完全看程序員如何設(shè)置跨域規(guī)則,跨域策略,不做深入講解,但是教你如何避開雷區(qū),先看看核心邏輯的截圖

服務器會判斷當前是否是預檢請求,如果是,則會調(diào)用一個處理內(nèi)部請求的方法,如圖

關(guān)鍵點:allowOrigin為什么為null,checkOrigin方法到底做了什么比較

知識點回顧

問題到這里很清晰了,當程序執(zhí)行到ObjectUtils.isEmpty(this.allowedOrigins)或者this.allowedOrigins.contains("*"),if語句的條件不成立了,因為this.allowedOrigins并不包含客戶端的域名,也就是例子中的https://www.bilbili.com或者https://www.zhihu.com,我們要處理的正是allowedOrigins,

private List<String> allowedOrigins;

他是以數(shù)組的形式被持有的,有很多個API可以給這個數(shù)組初始化值,在我的代碼中,只展示一種,因為我們要學的不是API,而是發(fā)現(xiàn)問題,拆分問題,解決問題的心法,API什么的不重要。

以上介紹了什么是跨域,跨域的情形,以及預檢請求作為web瀏覽器的規(guī)范,以及服務器如何處理預檢請求,瀏覽器對于未通過的預檢請求會以什么形式展示給用戶,接下來告訴大家如何解決這種小小的問題~

springboot解決跨域的方式非常之多,但是從最底層解決,往往能學到更多指定問題之外的知識

SpringBoot允許跨域的后端代碼

@Configuration
public class CorsConfig {
    @Bean
    public CorsFilter corsFilter() {
        UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
        CorsConfiguration config = new CorsConfiguration();
        //config.setAllowCredentials(true); // 允許發(fā)送憑據(jù),雷區(qū)
        config.addAllowedOrigin("*"); //允許任意域名跨域訪問接口
        config.addAllowedHeader("*"); // 允許所有頭部信息
        config.addAllowedMethod("*"); // 允許所有請求方法
        source.registerCorsConfiguration("/**", config); // 應用于所有路徑
        return new CorsFilter(source);
    }
}

這段配置足已解決前端跨域問題,之前說的雷區(qū)就是允許發(fā)送憑據(jù)的代碼和config.addAllowedOrigin("*");不可以一起使用,否則會報錯。到這里,一切OK,前端跨域的問題已經(jīng)解決~

給大家一段便捷的JS代碼用來測試跨域問題,JS代碼不做解釋,相信看懂不成問題

模擬跨域的JS代碼

var xhr = new XMLHttpRequest();
xhr.open('post', 'http://localhost:8081/admin/captcha/v1/generateCaptcha');
xhr.setRequestHeader('Content-Type', 'application/json'); // 設(shè)置請求頭
xhr.setRequestHeader('authracation', 'abcdefghijklmnopqrstuvwxyz'); // 設(shè)置請求頭
xhr.onload = function(e) {
    var xhr = e.target;
    console.log(xhr.responseText);
};
xhr.send('{}');

這段js代碼,按F12,在瀏覽器的控制臺中直接執(zhí)行,支持IE和Google瀏覽器,親測有效,需要根據(jù)實際的請求進行微調(diào),不要在你自己的WEB項目或者API文檔頁面打開,否則無法達到測試跨域的效果,具體原因,我相信你理解了上面的知識點之后應該能明白。解決問題的代碼很少,但是知識點并不少,留心處處皆學問哈

到此這篇關(guān)于Spring Boot CORS 配置詳解:允許跨域請求的最佳實踐的文章就介紹到這了,更多相關(guān)Spring Boot CORS 跨域請求內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • mybatis-plus如何使用mapper的xml

    mybatis-plus如何使用mapper的xml

    這篇文章主要介紹了mybatis-plus如何使用mapper的xml問題,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2023-06-06
  • Mybatis如何直接執(zhí)行SQL語句

    Mybatis如何直接執(zhí)行SQL語句

    這篇文章主要介紹了Mybatis如何直接執(zhí)行SQL語句,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2022-08-08
  • Java超詳細透徹講解static

    Java超詳細透徹講解static

    static關(guān)鍵字基本概念我們可以一句話來概括:方便在沒有創(chuàng)建對象的情況下來進行調(diào)用。也就是說:被static關(guān)鍵字修飾的不需要創(chuàng)建對象去調(diào)用,直接根據(jù)類名就可以去訪問,讓我們來了解一下你可能還不知道情況
    2022-05-05
  • SpringBoot或SpringAI對接DeepSeek大模型的詳細步驟

    SpringBoot或SpringAI對接DeepSeek大模型的詳細步驟

    這篇文章主要介紹了DeepSeek智能助手的使用方法和步驟,包括引入庫、配置環(huán)境變量和配置,文章詳細描述了流式請求和非流式請求的實現(xiàn)方式,需要的朋友可以參考下
    2025-02-02
  • java 同步器SynchronousQueue詳解及實例

    java 同步器SynchronousQueue詳解及實例

    這篇文章主要介紹了java 同步器SynchronousQueue詳解及實例的相關(guān)資料,需要的朋友可以參考下
    2017-05-05
  • Java詳解對象終止方法finalize()的用法

    Java詳解對象終止方法finalize()的用法

    在前面的 jvm 中, 需要補充幾個部分的內(nèi)容, 接著來看 finalize() 機制, 它可以使接近死亡的對象復活, 下來我們來看是怎么一回事
    2022-05-05
  • 詳解Java并發(fā)編程中的優(yōu)先級隊列PriorityBlockingQueue

    詳解Java并發(fā)編程中的優(yōu)先級隊列PriorityBlockingQueue

    PriorityBlockingQueue是Java中實現(xiàn)了堆數(shù)據(jù)結(jié)構(gòu)的線程安全的有界阻塞隊列。本文將會深入解讀PriorityBlockingQueue的源碼實現(xiàn),感興趣的可以了解一下
    2023-05-05
  • 帶你了解Java數(shù)據(jù)結(jié)構(gòu)和算法之哈希表

    帶你了解Java數(shù)據(jù)結(jié)構(gòu)和算法之哈希表

    這篇文章主要為大家介紹了Java數(shù)據(jù)結(jié)構(gòu)和算法之哈希表,具有一定的參考價值,感興趣的小伙伴們可以參考一下,希望能夠給你帶來幫助
    2022-01-01
  • Springboot導入本地jar后 打包依賴無法加入的解決方案

    Springboot導入本地jar后 打包依賴無法加入的解決方案

    這篇文章主要介紹了Springboot導入本地jar后 打包依賴無法加入的解決方案,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2021-11-11
  • Spring的懶加載機制原理和配置詳解

    Spring的懶加載機制原理和配置詳解

    這篇文章主要介紹了Spring的懶加載機制原理和配置詳解,Spring提供了懶加載機制,所謂的懶加載機制就是可以規(guī)定指定的bean不在啟動時立即創(chuàng)建,而是在后續(xù)第一次用到時才創(chuàng)建,從而減輕在啟動過程中對時間和內(nèi)存的消耗,需要的朋友可以參考下
    2023-10-10

最新評論