什么是跨域?
創(chuàng)新互聯(lián)公司堅(jiān)持“要么做到,要么別承諾”的工作理念,服務(wù)領(lǐng)域包括:網(wǎng)站設(shè)計(jì)、成都網(wǎng)站制作、企業(yè)官網(wǎng)、英文網(wǎng)站、手機(jī)端網(wǎng)站、網(wǎng)站推廣等服務(wù),滿足客戶于互聯(lián)網(wǎng)時(shí)代的邱縣網(wǎng)站設(shè)計(jì)、移動(dòng)媒體設(shè)計(jì)的需求,幫助企業(yè)找到有效的互聯(lián)網(wǎng)解決方案。努力成為您成熟可靠的網(wǎng)絡(luò)建設(shè)合作伙伴!
定義:瀏覽器從一個(gè)域名的網(wǎng)頁取請(qǐng)求另一個(gè)域名下的東西。通俗點(diǎn)說,瀏覽器直接從A域訪問B域中的資源是不被允許的,如果想要訪問,就需要進(jìn)行一步操作,這操作就叫“跨域”。例如,你從百度的頁面,點(diǎn)擊一個(gè)按鈕,請(qǐng)求了新浪的一個(gè)接口,這就進(jìn)行了跨域。不單單只有域名不同就是跨域,域名、端口、協(xié)議其一不同就是不同的域,請(qǐng)求資源需要跨域。
為什么要跨域?
為什么需要跨域,而不直接訪問其他域下的資源呢?這是瀏覽器的限制,專業(yè)點(diǎn)說叫瀏覽器同源策略限制。主要是為了安全考慮?,F(xiàn)在的安全框架,一般請(qǐng)求的時(shí)候header中不是都存?zhèn)€token嘛,你要是用這個(gè)token去正常訪問A域下的東西是沒問題的,然后又去訪問了B域,結(jié)果陰差陽錯(cuò)的還帶著這個(gè)token,那么B域,或者說B網(wǎng)站是不是就可以拿著你的token去A域下做點(diǎn)什么呢,這就相當(dāng)危險(xiǎn)了。所以瀏覽器加上了所謂的瀏覽器同源策略限制。但是為了我們真的需要從A域下訪問B的資源(正常訪問),就需要用到跨域,跨越這個(gè)限制了。
SpringBoot解決跨域問題
SpringBoot可以基于Cors解決跨域問題,Cors是一種機(jī)制,告訴我們的后臺(tái),哪邊(origin )來的請(qǐng)求可以訪問服務(wù)器的數(shù)據(jù)。
全局配置
配置實(shí)例如下:
@Configuration public class CorsConfig implements WebMvcConfigurer { @Override public void addCorsMappings(CorsRegistry registry) { registry.addMapping("/**") .allowedOrigins("*") .allowCredentials(true) .allowedMethods("GET", "POST", "PUT", "DELETE", "OPTIONS") .maxAge(3600); } }
首先實(shí)現(xiàn)了WebMvcConfigurer 接口,WebMvcConfigurer 這個(gè)接口十分強(qiáng)大,里面還有很多可用的方法,在SpringBoot2.0里面可以解決WebMvcConfigurerAdapter曾經(jīng)的部分任務(wù)。其中一個(gè)方法就是addCorsMappings(),是專門為開發(fā)人員解決跨域而誕生的接口。其中構(gòu)造參數(shù)為CorsRegistry。
看下CorsRegistry源碼,十分簡(jiǎn)單:
public class CorsRegistry { private final List<CorsRegistration> registrations = new ArrayList<>(); public CorsRegistration addMapping(String pathPattern) { CorsRegistration registration = new CorsRegistration(pathPattern); this.registrations.add(registration); return registration; } protected Map<String, CorsConfiguration> getCorsConfigurations() { Map<String, CorsConfiguration> configs = new LinkedHashMap<>(this.registrations.size()); for (CorsRegistration registration : this.registrations) { configs.put(registration.getPathPattern(), registration.getCorsConfiguration()); } return configs; } }
可以看出CorsRegistry 有個(gè)屬性registrations ,按道理可以根據(jù)不同的項(xiàng)目路徑進(jìn)行定制訪問行為,但是我們示例直接將pathPattern 設(shè)置為 /**,也就是說已覆蓋項(xiàng)目所有路徑,只需要?jiǎng)?chuàng)建一個(gè)CorsRegistration就好。getCorsConfigurations(),這個(gè)方法是獲取所有CorsConfiguration的Map集合,key值為傳入路徑pathPattern。
回到示例代碼CorsConfig中,registry對(duì)象addMapping()增加完傳入路徑pathPattern之后,return了一個(gè)CorsRegistration對(duì)象,是進(jìn)行更多的配置,看一下CorsRegistration的代碼,看看我們能配些什么?
public class CorsRegistration { //傳入的路徑 private final String pathPattern; //配置信息實(shí)體類 private final CorsConfiguration config; //構(gòu)造方法 public CorsRegistration(String pathPattern) { this.pathPattern = pathPattern; //原生注釋看到了一個(gè) @CrossOrigin 這個(gè)注解,待會(huì)看看是什么 // Same implicit default values as the @CrossOrigin annotation + allows simple methods this.config = new CorsConfiguration().applyPermitDefaultValues(); } //允許哪些源網(wǎng)站訪問,默認(rèn)所有 public CorsRegistration allowedOrigins(String... origins) { this.config.setAllowedOrigins(Arrays.asList(origins)); return this; } //允許何種方式訪問,默認(rèn)簡(jiǎn)單方式,即:GET,HEAD,POST public CorsRegistration allowedMethods(String... methods) { this.config.setAllowedMethods(Arrays.asList(methods)); return this; } //設(shè)置訪問header,默認(rèn)所有 public CorsRegistration allowedHeaders(String... headers) { this.config.setAllowedHeaders(Arrays.asList(headers)); return this; } //設(shè)置response headers,默認(rèn)沒有(什么都不設(shè)置) public CorsRegistration exposedHeaders(String... headers) { this.config.setExposedHeaders(Arrays.asList(headers)); return this; } //是否瀏覽器應(yīng)該發(fā)送credentials,例如cookies Access-Control-Allow-Credentials public CorsRegistration allowCredentials(boolean allowCredentials) { this.config.setAllowCredentials(allowCredentials); return this; } //設(shè)置等待時(shí)間,默認(rèn)1800秒 public CorsRegistration maxAge(long maxAge) { this.config.setMaxAge(maxAge); return this; } protected String getPathPattern() { return this.pathPattern; } protected CorsConfiguration getCorsConfiguration() { return this.config; } }
局部配置
剛才遇到一個(gè)@CrossOrigin這個(gè)注解,看看它是干什么的?
@Target({ ElementType.METHOD, ElementType.TYPE }) @Retention(RetentionPolicy.RUNTIME) @Documented public @interface CrossOrigin { /** @deprecated as of Spring 5.0, in favor of {@link CorsConfiguration#applyPermitDefaultValues} */ @Deprecated String[] DEFAULT_ORIGINS = { "*" }; /** @deprecated as of Spring 5.0, in favor of {@link CorsConfiguration#applyPermitDefaultValues} */ @Deprecated String[] DEFAULT_ALLOWED_HEADERS = { "*" }; /** @deprecated as of Spring 5.0, in favor of {@link CorsConfiguration#applyPermitDefaultValues} */ @Deprecated boolean DEFAULT_ALLOW_CREDENTIALS = false; /** @deprecated as of Spring 5.0, in favor of {@link CorsConfiguration#applyPermitDefaultValues} */ @Deprecated long DEFAULT_MAX_AGE = 1800 /** * Alias for {@link #origins}. */ @AliasFor("origins") String[] value() default {}; @AliasFor("value") String[] origins() default {}; String[] allowedHeaders() default {}; String[] exposedHeaders() default {}; RequestMethod[] methods() default {}; String allowCredentials() default ""; long maxAge() default -1; }
這個(gè)注解可以作用于方法或者類上,實(shí)現(xiàn)局部跨域,你會(huì)發(fā)現(xiàn)除了設(shè)置路徑(因?yàn)闆]必要了,都定位到局部了)其他的參數(shù)與全局類似。
小結(jié)
SpringBoot可以基于Cors解決跨域問題,可以設(shè)置全局跨域,也可以實(shí)現(xiàn)局部跨域,靈活配置方便使用。
以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持創(chuàng)新互聯(lián)。
分享標(biāo)題:SpringBoot跨域問題的解決方案
當(dāng)前鏈接:http://jinyejixie.com/article34/jjppse.html
成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供定制網(wǎng)站、靜態(tài)網(wǎng)站、網(wǎng)站策劃、品牌網(wǎng)站設(shè)計(jì)、服務(wù)器托管、網(wǎng)站建設(shè)
聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請(qǐng)盡快告知,我們將會(huì)在第一時(shí)間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如需處理請(qǐng)聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時(shí)需注明來源: 創(chuàng)新互聯(lián)