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

SpringBoot之跨域過濾器配置允許跨域訪問方式

 更新時間:2022年07月01日 15:51:11   作者:Moshow鄭鍇  
這篇文章主要介紹了SpringBoot之跨域過濾器配置允許跨域訪問方式,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教

SpringBoot跨域過濾器配置允許跨域訪問

跨域請求

當(dāng)一個資源從與該資源本身所在的服務(wù)器不同的域或端口請求一個資源時,資源會發(fā)起一個跨域 HTTP 請求。

出于安全原因,瀏覽器限制從腳本內(nèi)發(fā)起的跨源HTTP請求。 例如,XMLHttpRequest和Fetch API遵循同源策略。 這意味著使用這些API的Web應(yīng)用程序只能從加載應(yīng)用程序的同一個域請求HTTP資源,除非使用CORS頭文件。

問題背景

如果前端提示”Access-Control-Allow-Origin”問題

XMLHttpRequest cannot load http://xxxxxxxxxx/. No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'null' is therefore not allowed access.

跨域過濾器

那么需要再SpringBoot2配置跨域過濾器允許跨域訪問。

import java.io.IOException;
import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.springframework.stereotype.Component;
@Component ?
public class CorsFilter implements Filter { ?
? ? @Override
? ? public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) throws IOException, ServletException { ?
? ? ? ? HttpServletRequest request = (HttpServletRequest) req;
? ? ? ? HttpServletResponse response = (HttpServletResponse) res; ?
? ? ? ? response.setHeader("Access-Control-Allow-Origin", "*"); ?
? ? ? ? response.setHeader("Access-Control-Allow-Methods", "POST, GET, OPTIONS, DELETE, PUT, GET"); ?
? ? ? ? response.setHeader("Access-Control-Max-Age", "3600"); ?
? ? ? ? response.setHeader("Access-Control-Allow-Headers", "x-requested-with"); ?
? ? ? ? chain.doFilter(req, res); ?
? ? } ?
? ? @Override
? ? public void init(FilterConfig filterConfig) {} ?
? ? @Override
? ? public void destroy() {} ?
} ?

跨域功能改進(jìn)

如果需要顯示跨域地址,還可以在里面加上訪問來源打印語句,供排查

String curOrigin = request.getHeader("Origin");
System.out.println("###跨域過濾器->當(dāng)前訪問來源->"+curOrigin+"###"); ?

如果需要跨域權(quán)限,可以判斷一下來源

String curOrigin = request.getHeader("Origin");
System.out.println("###跨域過濾器->當(dāng)前訪問來源->"+curOrigin+"###"); ?
if(curOrigin.indexOf("127.0.0.1:8080")>-1){
? ? response.setHeader("Access-Control-Allow-Origin", "*");
}

關(guān)于跨域訪問更專業(yè)的內(nèi)容,可以訪問Mozilla官方的一個關(guān)于CROS文章

https://developer.mozilla.org/zh-CN/docs/Web/HTTP/Access_control_CORS

SpringBoot跨域設(shè)置(CORS)

一、什么是跨域

請求url的協(xié)議、域名、端口三者有任意一個不同即為跨域。跨域問題是因?yàn)闉g覽器的同源策略的限制而產(chǎn)生的。

  • 同源:請求url的協(xié)議、域名、端口三者都相同即為同源(同一個域)。
  • 同源策略:同源策略(Sameoriginpolicy)是一種約定,他是瀏覽器最核心也最基本的安全功能。同源策略會阻止非同源(同一個域)的內(nèi)容進(jìn)行交互。

同源策略的限制:

  • 無法讀取非同源網(wǎng)頁的Cookie、LocalStorage和IndexedDB
  • 無法接觸非同源網(wǎng)頁的DOM
  • 無法向非同源地址發(fā)送AJAX請求

瀏覽器的同源策略會限制跨域請求,限制的方式一般有兩種:

  • 瀏覽器限制發(fā)起跨域請求;
  • 跨域請求可以正常發(fā)起,但是返回的結(jié)果被瀏覽器攔截了。

一般瀏覽器都是第二種方式限制跨域請求,那就是說請求已到達(dá)服務(wù)器,并有可能對數(shù)據(jù)庫里的數(shù)據(jù)進(jìn)行了操作,但是返回的結(jié)果被瀏覽器攔截了,那么我們就獲取不到返回結(jié)果,這是一次失敗的請求,但是可能對數(shù)據(jù)庫里的數(shù)據(jù)產(chǎn)生了影響。

為了防止這種情況的發(fā)生,規(guī)范要求,對這種可能對服務(wù)器數(shù)據(jù)產(chǎn)生副作用的HTTP請求方法,瀏覽器必須先使用OPTIONS方法發(fā)起一個預(yù)檢請求,從而獲知服務(wù)器是否允許該跨域請求:如果允許,就發(fā)送帶數(shù)據(jù)的真實(shí)請求;如果不允許,則阻止發(fā)送帶數(shù)據(jù)的真實(shí)請求。

二、跨域資源共享(CORS)

解決非同源內(nèi)容無法交互的問題,目前主流的解決方案就是:CORS(跨域資源共享)。

跨域資源共享(Cross-origin Resource Sharing)簡稱CORS,它突破了一個請求在瀏覽器發(fā)出只能在同源的情況下向服務(wù)器獲取數(shù)據(jù)的限制。

CORS約定服務(wù)器端和瀏覽器在HTTP協(xié)議之上,通過一些額外HTTP頭部信息,進(jìn)行跨域資源共享的協(xié)商。服務(wù)器端和瀏覽器都必需遵循規(guī)范中的要求。

CORS把HTTP的跨域請求分成兩類,簡單請求和非簡單請求,不同請求按照不同的策略進(jìn)行跨域資源共享協(xié)商。

1. 簡單請求

簡單跨域請求需滿足的條件:

1.請求方法是GET、HEAD或者POST(POST時,Content-Type的值必須是application/x-www-form-urlencoded、multipart/form-data、text/plain中的一個值);

2.請求中沒有自定義HTTP請求頭。

HTTP頭只能時下面這些字段:

  • Accept
  • Accept-Language
  • Content-Language
  • DPR
  • Downlink
  • Save-Data
  • Viewport-Width
  • Width
  • Content-Type

以上兩點(diǎn)都滿足才是簡單跨域請求。

對于簡單跨域請求,處理方式如下:

1.瀏覽器要做的就是在HTTP請求頭中添加Origin,將JavaScript腳本所在域填充進(jìn)去,向其他域的服務(wù)器請求資源。

Origin: http://www.joker.com

Origin字段用來說明,本次請求來自哪個源(協(xié)議 + 域名 + 端口)。服務(wù)器根據(jù)這個值,決定是否同意這次請求。

2.服務(wù)器端收到一個簡單跨域請求后,根據(jù)資源權(quán)限配置,在響應(yīng)頭中添加Access-Control-Allow-Origin。

如果Origin指定的源,不在許可范圍內(nèi),服務(wù)器會返回一個正常的HTTP回應(yīng)。 但這個響應(yīng)頭信息沒有包含Access-Control-Allow-Origin字段,瀏覽器就知道該域名不在許可范圍內(nèi)。

如果Origin指定的域名在許可范圍內(nèi),服務(wù)器返回的響應(yīng),會多出幾個頭信息字段:

Access-Control-Allow-Origin: http://www.joker.com
Access-Control-Allow-Credentials: true
Access-Control-Expose-Headers: My-Token
  • Access-Control-Allow-Origin:該字段是必須的。它的值要么是請求時Origin字段的值,要么是一個*值,表示接受任意域名的請求。
  • Access-Control-Allow-Credentials: 該字段是可選的。它的值是一個布爾值,表示是否允許發(fā)送Cookie。默認(rèn)情況下,Cookie不包括在CORS請求之中。設(shè)為true,即表示服務(wù)器明確許可,Cookie可以包含在請求中,一起發(fā)給服務(wù)器。這個值也只能設(shè)為true,如果服務(wù)器不要瀏覽器發(fā)送Cookie,刪除該字段即可。
  • Access-Control-Expose-Headers:該字段是可選的。CORS請求時,XMLHttpRequest對象的getResponseHeader()方法只能拿到6個基本字段:Cache-Control、Content-Language、Content-Type、Expires、Last-Modified、Pragma。如果想拿到其他字段,就必須在Access-Control-Expose-Headers里面指定。

3.瀏覽器收到響應(yīng)后,通過獲取響應(yīng)頭中的Access-Control-Allow-Origin字段,來判斷如果當(dāng)前域已經(jīng)得到授權(quán),則將結(jié)果返回給JavaScript。否則瀏覽器忽略此次響應(yīng)。

2. 非簡單請求

非簡單跨域請求需滿足的條件:

  • 除GET、HEAD和POST(Content-Type的值是:application/x-www-form-urlencoded、multipart/form-data、text/plain中的一個值)以外的其他HTTP方法
  • 如:PUT、DELETE、TRACE、PATCH、POST(Content-Type的值是:application/json)。
  • 請求中有自定義HTTP頭部。

以上兩點(diǎn)只要至少滿足其中一點(diǎn)就是非簡單跨域請求。

對于非簡單跨域請求,處理方式如下:

1.瀏覽器在發(fā)送真實(shí)HTTP請求之前先發(fā)送一個OPTIONS的預(yù)檢請求,檢測服務(wù)器端是否支持真實(shí)請求進(jìn)行跨域資源訪問。

真實(shí)請求的信息在OPTIONS請求中通過請求頭中的Access-Control-Request-Method和Access-Control-Request-Headers字段來描述。此外與簡單跨域請求一樣,請求頭中也會有Origin字段。

Origin: http://www.joker.com
Access-Control-Request-Method: PUT
Access-Control-Request-Headers: Header1,Header2
  • Origin:必須字段,用于指定請求源。
  • Access-Control-Request-Method:必須字段,用于描述真實(shí)請求的方法(PUT、DELETE等)。
  • Access-Control-Request-Headers:指定真實(shí)請求會額外發(fā)送的請求頭字段信息。

2.服務(wù)器端接到預(yù)檢請求后,會檢查了Origin、Access-Control-Request-Method和Access-Control-Request-Headers字段,檢驗(yàn)是否允許跨源請求。

如果不允許該跨域請求,會返回一個正常的HTTP回應(yīng),但這個響應(yīng)頭信息沒有包含Access-Control-Allow-Origin字段,瀏覽器就知道該域名不在許可范圍內(nèi)。

如果允許該跨域請求,就會在響應(yīng)頭中放入Access-Control-Allow-Origin、Access-Control-Allow-Methods和Access-Control-Allow-Headers,分別表示允許跨域資源請求的域、請求方法和請求頭。此外,服務(wù)器端還可以在響應(yīng)頭中放入Access-Control-Max-Age,允許瀏覽器在指定時間內(nèi),無需再發(fā)送預(yù)檢請求進(jìn)行協(xié)商,直接用本次協(xié)商結(jié)果即可。

Access-Control-Allow-Origin: http://www.joker.com
Access-Control-Allow-Methods: GET, POST, PUT
Access-Control-Allow-Headers: Header1,Header2,Header3
Access-Control-Allow-Credentials: true
Access-Control-Max-Age: 1728000
  • Access-Control-Allow-Methods:該字段必需,它的值是逗號分隔的一個字符串,表明服務(wù)器支持的所有跨域請求的方法。注意,返回的是所有支持的方法,而不單是瀏覽器請求的那個方法。這是為了避免多次"預(yù)檢"請求。
  • Access-Control-Allow-Headers:如果瀏覽器請求包括Access-Control-Request-Headers字段,則Access-Control-Allow-Headers字段是必需的。它也是一個逗號分隔的字符串,表明服務(wù)器支持的所有頭信息字段,不限于瀏覽器在"預(yù)檢"中請求的字段。
  • Access-Control-Allow-Credentials: 該字段與簡單請求時的含義相同。它的值是一個布爾值,表示是否允許發(fā)送Cookie。默認(rèn)情況下,Cookie不包括在CORS請求之中。設(shè)為true,即表示服務(wù)器明確許可,Cookie可以包含在請求中,一起發(fā)給服務(wù)器。這個值也只能設(shè)為true,如果服務(wù)器不要瀏覽器發(fā)送Cookie,刪除該字段即可。
  • Access-Control-Max-Age: 該字段可選,用來指定本次預(yù)檢請求的有效期,單位為秒。上面結(jié)果中,有效期是20天(1728000秒),即允許緩存該條回應(yīng)1728000秒(即20天),在此期間,不用發(fā)出另一條預(yù)檢請求。

瀏覽器根據(jù)OPTIONS請求返回的結(jié)果來決定是否繼續(xù)發(fā)送真實(shí)的請求進(jìn)行跨域資源訪問。這個過程對真實(shí)請求的調(diào)用者來說是透明的。

三、SpringBoot設(shè)置CORS

SpringBoot設(shè)置CORS的的本質(zhì)都是通過設(shè)置響應(yīng)頭信息來告訴前端該請求是否支持跨域。

SpringBoot設(shè)置CORS的方式主要有以下三種。

1. 配置過濾器CorsFilter

@Configuration
public class CorsConfig {
?? ?
?? ?@Bean
? ? CorsFilter corsFilter() {
? ? ? ? CorsConfiguration configuration = new CorsConfiguration();
? ? ? ? configuration.setAllowedOrigins(Arrays.asList("*"));
? ? ? ? configuration.setAllowedMethods(Arrays.asList("*"));
? ? ? ? configuration.setAllowedHeaders(Arrays.asList("*"));
? ? ? ? configuration.setAllowCredentials(true);
? ? ? ? UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
? ? ? ? source.registerCorsConfiguration("/**", configuration);
? ? ? ? return new CorsFilter(source);
? ? }
}

2. 實(shí)現(xiàn)接口WebMvcConfigurer

@Configuration
public class WebMvcConfig implements WebMvcConfigurer {
?? ?
?? ?@Override
? ? public void addCorsMappings(CorsRegistry registry) {
? ? ? ? registry.addMapping("/**")
? ? ? ? ? ? ? ? .allowedOrigins("*")
? ? ? ? ? ? ? ? .allowedHeaders("*")
? ? ? ? ? ? ? ? .allowedMethods("*")
? ? ? ? ? ? ? ? .allowCredentials(true);
? ? }
}

3. 使用注解@CrossOrigin

@CrossOrigin注解可以用在類或者方法上

用在控制器類上,表示 該類的所有方法都允許跨域

@RestController
@CrossOrigin
public class TestController {
? ??
? ? @GetMapping("test")
? ? public String test() {
? ? ? ? return "success";
? ? }
}

用在控制器方法上,表示該方法都允許跨域

@RestController
public class TestController {
? ? @CrossOrigin
? ? @GetMapping("test")
? ? public String test() {
? ? ? ? return "success";
? ? }
}

@CrossOrigin注解源碼

@Target({ElementType.TYPE, ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface CrossOrigin {
??
? /**
? ?* 這origins和value是一樣的
? ?* 允許來源域名的列表,例如 www.baidu.com,匹配的域名是跨域預(yù)請求Response頭中的Access-Control-Aloow_origin字段值。
? ?* 不設(shè)置確切值時默認(rèn)支持所有域名跨域訪問。
? ?*/
? @AliasFor("origins")
? String[] value() default {};
? @AliasFor("value")
? String[] origins() default {};
? /**
? ?* 高版本下Spring2.4.4使用originPatterns而不是value和origins
? ?*/
? String[] originPatterns() default {};
? /**
? ?* 跨域請求中允許的請求頭中的字段類型, 該值對應(yīng)跨域預(yù)請求Response頭中的Access-Control-Allow-Headers字段值。
? ?* 不設(shè)置確切值默認(rèn)支持所有的header字段(Cache-Controller、Content-Language、Content-Type、Expires、Last-Modified、Pragma)跨域訪問
? ?*/
? String[] allowedHeaders() default {};
? /**
? ?* 跨域請求請求頭中允許攜帶的除Cache-Controller、Content-Language、Content-Type、Expires、Last-Modified、Pragma這六個基本字段之外的其他字段信息,
? ?* 對應(yīng)的是跨域請求Response頭中的Access-control-Expose-Headers字段值
? ?*/
? String[] exposedHeaders() default {};
? /**
? ?* 跨域HTTP請求中支持的HTTP請求類型(GET、POST...),
? ?* 不指定確切值時默認(rèn)與 Controller 方法中的 methods 字段保持一致。
? ?*/
? RequestMethod[] methods() default {};
? /**
? ?* 瀏覽器是否將本域名下的cookie信息攜帶至跨域服務(wù)器中。默認(rèn)攜帶至跨域服務(wù)器中,但要實(shí)現(xiàn)cookie共享還需要前端在AJAX請求中打開withCredentials屬性。
? ?* 該值對應(yīng)的是是跨域請求 Response 頭中的 'Access-Control-Allow-Credentials' 字段值。
? ?*/
? String allowCredentials() default "";
? /**
? ?* 該值的目的是減少瀏覽器預(yù)檢請求/響應(yīng)交互的數(shù)量。默認(rèn)值1800s。設(shè)置了該值后,瀏覽器將在設(shè)置值的時間段內(nèi)對該跨域請求不再發(fā)起預(yù)請求。
? ?* 該值對應(yīng)的是是跨域請求Response頭中的Access-Control-Max-Age字段值,表示預(yù)檢請求響應(yīng)的緩存持續(xù)的最大時間。
? ?*/
? long maxAge() default -1;
}

以上為個人經(jīng)驗(yàn),希望能給大家一個參考,也希望大家多多支持腳本之家。

相關(guān)文章

  • 詳解關(guān)于java文件下載文件名亂碼問題解決方案

    詳解關(guān)于java文件下載文件名亂碼問題解決方案

    這篇文章主要介紹了詳解關(guān)于java文件下載文件名亂碼問題解決方案,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2020-01-01
  • 基于SpringBoot使用MyBatis插件的問題

    基于SpringBoot使用MyBatis插件的問題

    MyBatis-Plus并不能為我們解決所有問題,例如一些復(fù)雜的SQL,多表聯(lián)查,我們就需要自己去編寫代碼和SQL語句,我們該如何快速的解決這個問題呢,這個時候可以使用MyBatisX插件,今天小編給大家?guī)砹薙pringBoot使用MyBatis插件問題,感興趣的朋友一起看看吧
    2022-03-03
  • 詳細(xì)介紹SpringCloud之Ribbon

    詳細(xì)介紹SpringCloud之Ribbon

    本篇文章主要介紹了SpringCloud之Ribbon,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2018-01-01
  • Java8中Stream的詳細(xì)使用方法大全

    Java8中Stream的詳細(xì)使用方法大全

    Java8的另一大亮點(diǎn)Stream,它與java.io包里的InputStream和OutputStream是完全不同的概念,下面這篇文章主要給大家介紹了關(guān)于Java8中Stream詳細(xì)使用方法的相關(guān)資料,需要的朋友可以參考下
    2022-06-06
  • Mybatis-Plus實(shí)體類注解方法與mapper層和service層的CRUD方法

    Mybatis-Plus實(shí)體類注解方法與mapper層和service層的CRUD方法

    CRUD是指在做計算處理時的增加(Create)、讀取查詢(Retrieve)、更新(Update)和刪除(Delete)幾個單詞的首字母簡寫。主要被用在描述軟件系統(tǒng)中DataBase或者持久層的基本操作功能,下面讓我們一起看看吧
    2022-03-03
  • Java?AQS?線程安全同步隊(duì)列的實(shí)現(xiàn)

    Java?AQS?線程安全同步隊(duì)列的實(shí)現(xiàn)

    AQS 同步隊(duì)列是很多的 Java 線程安全對象的實(shí)現(xiàn),例如 ReentrantLock, Semaphore, CountDownLatch, ReentrantReadWriteLock 等等,本文就介紹了Java?AQS?線程安全同步隊(duì)列的實(shí)現(xiàn),感興趣的可以了解一下
    2023-08-08
  • 淺談javap命令拆解字節(jié)碼文件

    淺談javap命令拆解字節(jié)碼文件

    這篇文章主要介紹了拆解字節(jié)碼文件javap命令,對反編譯感興趣的同學(xué)可以參考下
    2021-04-04
  • Springmvc返回html頁面問題如何解決

    Springmvc返回html頁面問題如何解決

    這篇文章主要介紹了Springmvc返回html頁面問題如何解決,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友可以參考下
    2020-10-10
  • java字符串遍歷以及統(tǒng)計字符串中各類字符

    java字符串遍歷以及統(tǒng)計字符串中各類字符

    這篇文章主要為大家詳細(xì)介紹了java字符串遍歷以及字符串中各類字符統(tǒng)計,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2018-03-03
  • SpringCloud Gateway使用詳解

    SpringCloud Gateway使用詳解

    Spring Cloud Gateway是一個基于Spring Boot 2.x和Spring WebFlux的API網(wǎng)關(guān),可以幫助我們構(gòu)建微服務(wù)架構(gòu)中的統(tǒng)一入口。感興趣的同學(xué)可以參考一下
    2023-04-04

最新評論