SpringBoot之跨域過(guò)濾器配置允許跨域訪問(wèn)方式_第1頁(yè)
SpringBoot之跨域過(guò)濾器配置允許跨域訪問(wèn)方式_第2頁(yè)
SpringBoot之跨域過(guò)濾器配置允許跨域訪問(wèn)方式_第3頁(yè)
SpringBoot之跨域過(guò)濾器配置允許跨域訪問(wèn)方式_第4頁(yè)
SpringBoot之跨域過(guò)濾器配置允許跨域訪問(wèn)方式_第5頁(yè)
已閱讀5頁(yè),還剩8頁(yè)未讀, 繼續(xù)免費(fèi)閱讀

下載本文檔

版權(quán)說(shuō)明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)

文檔簡(jiǎn)介

第SpringBoot之跨域過(guò)濾器配置允許跨域訪問(wèn)方式目錄SpringBoot跨域過(guò)濾器配置允許跨域訪問(wèn)跨域請(qǐng)求問(wèn)題背景跨域過(guò)濾器跨域功能改進(jìn)SpringBoot跨域設(shè)置(CORS)一、什么是跨域二、跨域資源共享(CORS)1.簡(jiǎn)單請(qǐng)求2.非簡(jiǎn)單請(qǐng)求三、SpringBoot設(shè)置CORS

SpringBoot跨域過(guò)濾器配置允許跨域訪問(wèn)

跨域請(qǐng)求

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

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

問(wèn)題背景

如果前端提示Access-Control-Allow-Origin問(wèn)題

XMLHttpRequestcannotloadhttp://xxxxxxxxxx/.NoAccess-Control-Allow-Originheaderispresentontherequestedresource.Originnullisthereforenotallowedaccess.

跨域過(guò)濾器

那么需要再SpringBoot2配置跨域過(guò)濾器允許跨域訪問(wèn)。

importjava.io.IOException;

importjavax.servlet.Filter;

importjavax.servlet.FilterChain;

importjavax.servlet.FilterConfig;

importjavax.servlet.ServletException;

importjavax.servlet.ServletRequest;

importjavax.servlet.ServletResponse;

importjavax.servlet.http.HttpServletRequest;

importjavax.servlet.http.HttpServletResponse;

importorg.springframework.stereotype.Component;

@Component

publicclassCorsFilterimplementsFilter{

@Override

publicvoiddoFilter(ServletRequestreq,ServletResponseres,FilterChainchain)throwsIOException,ServletException{

HttpServletRequestrequest=(HttpServletRequest)req;

HttpServletResponseresponse=(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

publicvoidinit(FilterConfigfilterConfig){}

@Override

publicvoiddestroy(){}

}

跨域功能改進(jìn)

如果需要顯示跨域地址,還可以在里面加上訪問(wèn)來(lái)源打印語(yǔ)句,供排查

StringcurOrigin=request.getHeader("Origin");

System.out.println("###跨域過(guò)濾器-當(dāng)前訪問(wèn)來(lái)源-"+curOrigin+"###");

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

StringcurOrigin=request.getHeader("Origin");

System.out.println("###跨域過(guò)濾器-當(dāng)前訪問(wèn)來(lái)源-"+curOrigin+"###");

if(curOrigin.indexOf(":8080")-1){

response.setHeader("Access-Control-Allow-Origin","*");

}

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

/zh-CN/docs/Web/HTTP/Access_control_CORS

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

一、什么是跨域

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

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

同源策略的限制:

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

瀏覽器的同源策略會(huì)限制跨域請(qǐng)求,限制的方式一般有兩種:

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

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

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

二、跨域資源共享(CORS)

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

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

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

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

1.簡(jiǎn)單請(qǐng)求

簡(jiǎn)單跨域請(qǐng)求需滿足的條件:

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

2.請(qǐng)求中沒(méi)有自定義HTTP請(qǐng)求頭。

HTTP頭只能時(shí)下面這些字段:

AcceptAccept-LanguageContent-LanguageDPRDownlinkSave-DataViewport-WidthWidthContent-Type

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

對(duì)于簡(jiǎn)單跨域請(qǐng)求,處理方式如下:

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

Origin:

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

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

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

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

Access-Control-Allow-Origin:

Access-Control-Allow-Credentials:true

Access-Control-Expose-Headers:My-Token

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

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

2.非簡(jiǎn)單請(qǐng)求

非簡(jiǎn)單跨域請(qǐng)求需滿足的條件:

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

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

對(duì)于非簡(jiǎn)單跨域請(qǐng)求,處理方式如下:

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

真實(shí)請(qǐng)求的信息在OPTIONS請(qǐng)求中通過(guò)請(qǐng)求頭中的Access-Control-Request-Method和Access-Control-Request-Headers字段來(lái)描述。此外與簡(jiǎn)單跨域請(qǐng)求一樣,請(qǐng)求頭中也會(huì)有Origin字段。

Origin:

Access-Control-Request-Method:PUT

Access-Control-Request-Headers:Header1,Header2

Origin:必須字段,用于指定請(qǐng)求源。Access-Control-Request-Method:必須字段,用于描述真實(shí)請(qǐng)求的方法(PUT、DELETE等)。Access-Control-Request-Headers:指定真實(shí)請(qǐng)求會(huì)額外發(fā)送的請(qǐng)求頭字段信息。

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

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

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

Access-Control-Allow-Origin:

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

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

三、SpringBoot設(shè)置CORS

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

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

1.配置過(guò)濾器CorsFilter

@Configuration

publicclassCorsConfig{

@Bean

CorsFiltercorsFilter(){

CorsConfigurationconfiguration=newCorsConfiguration();

configuration.setAllowedOrigins(Arrays.asList("*"));

configuration.setAllowedMethods(Arrays.asList("*"));

configuration.setAllowedHeaders(Arrays.asList("*"));

configuration.setAllowCredentials(true);

UrlBasedCorsConfigurationSourcesource=newUrlBasedCorsConfigurationSource();

source.registerCorsConfiguration("/**",configuration);

returnnewCorsFilter(source);

}

}

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

@Configuration

publicclassWebMvcConfigimplementsWebMvcConfigurer{

@Override

publicvoidaddCorsMappings(CorsRegistryregistry){

registry.addMapping("/**")

.allowedOrigins("*")

.allowedHeaders("*")

.allowedMethods("*")

.allowCredentials(true);

}

}

3.使用注解@CrossOrigin

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

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

@RestController

@CrossOrigin

publicclassTestController{

@GetMapping("test")

publicStringtest(){

return"success";

}

}

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

@RestController

publicclassTestController{

@CrossOrigin

@GetMapping("test")

publicStringtest(){

return"success";

}

}

@CrossOrigin注解源碼

@Target({ElementType.TYPE,ElementType.METHOD})

@Retention(RetentionPolicy.RUNTIME)

@Documented

public@interfaceCrossOrigin{

/**

*這origins和value是一樣的

*允許來(lái)源域名的列表,例如,匹配的域名是跨域預(yù)請(qǐng)求Response頭中的Access-Control-Aloow_origin字段值。

*不設(shè)置確切值時(shí)默認(rèn)支持所有域名跨域訪問(wèn)。

*/

@AliasFor("origins")

String[]value()default{};

@AliasFor("value")

String[]origins()default{};

/**

*高版本下Spring2.4.4使用originPatterns而不是value和origins

*/

String[]originPatterns()default{};

/**

*跨域請(qǐng)求中允許的請(qǐng)求頭中的字段類型,該值對(duì)應(yīng)跨域預(yù)請(qǐng)求Response頭中的Access-Control-Allow-Headers字段值。

*

溫馨提示

  • 1. 本站所有資源如無(wú)特殊說(shuō)明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁(yè)內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒(méi)有圖紙預(yù)覽就沒(méi)有圖紙。
  • 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫(kù)網(wǎng)僅提供信息存儲(chǔ)空間,僅對(duì)用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對(duì)用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對(duì)任何下載內(nèi)容負(fù)責(zé)。
  • 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請(qǐng)與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對(duì)自己和他人造成任何形式的傷害或損失。

評(píng)論

0/150

提交評(píng)論