一、為什么會出現(xiàn)跨域問題
出于瀏覽器的同源策略限制。同源策略(Sameoriginpolicy)是一種約定,它是瀏覽器最核心也最基本的安全功能,如果缺少了同源策略,則瀏覽器的正常功能可能都會受到影響。可以說Web是構(gòu)建在同源策略基礎(chǔ)之上的,瀏覽器只是針對同源策略的一種實(shí)現(xiàn)。
同源策略會阻止一個(gè)域的javascript腳本和另外一個(gè)域的內(nèi)容進(jìn)行交互。所謂同源(即指在同一個(gè)域)就是兩個(gè)頁面具有相同的協(xié)議(protocol),主機(jī)(host)和端口號(port)
二、什么是跨域
當(dāng)一個(gè)請求url的協(xié)議、域名、端口三者之間任意一個(gè)與當(dāng)前頁面url不同即為跨域
三、非同源限制
無法讀取非同源網(wǎng)頁的 Cookie、LocalStorage 和 IndexedDB
無法接觸非同源網(wǎng)頁的 DOM
無法向非同源地址發(fā)送 AJAX 請求
四、java 后端 實(shí)現(xiàn) CORS 跨域請求的方式
對于 CORS的跨域請求,主要有以下幾種方式可供選擇:
返回新的CorsFilter
重寫 WebMvcConfigurer
使用注解 @CrossOrigin
手動(dòng)設(shè)置響應(yīng)頭 (HttpServletResponse)
自定 web filter 實(shí)現(xiàn)跨域
注意:
CorFilter / WebMvConfigurer / @CrossOrigin 需要 SpringMVC 4.2以上版本才支持,對應(yīng)springBoot 1.3版本以上
上面前兩種方式屬于全局 CORS 配置,后兩種屬于局部 CORS配置。如果使用了局部跨域是會覆蓋全局跨域的規(guī)則,所以可以通過 @CrossOrigin 注解來進(jìn)行細(xì)粒度更高的跨域資源控制。
其實(shí)無論哪種方案,最終目的都是修改響應(yīng)頭,向響應(yīng)頭中添加瀏覽器所要求的數(shù)據(jù),進(jìn)而實(shí)現(xiàn)跨域
1.返回新的 CorsFilter(全局跨域)
在任意配置類,返回一個(gè) 新的 CorsFIlter Bean ,并添加映射路徑和具體的CORS配置路徑。
@Configuration publicclassGlobalCorsConfig{ @Bean publicCorsFiltercorsFilter(){ //1.添加CORS配置信息 CorsConfigurationconfig=newCorsConfiguration(); //放行哪些原始域 config.addAllowedOrigin("*"); //是否發(fā)送Cookie config.setAllowCredentials(true); //放行哪些請求方式 config.addAllowedMethod("*"); //放行哪些原始請求頭部信息 config.addAllowedHeader("*"); //暴露哪些頭部信息 config.addExposedHeader("*"); //2.添加映射路徑 UrlBasedCorsConfigurationSourcecorsConfigurationSource=newUrlBasedCorsConfigurationSource(); corsConfigurationSource.registerCorsConfiguration("/**",config); //3.返回新的CorsFilter returnnewCorsFilter(corsConfigurationSource); } }
2. 重寫 WebMvcConfigurer(全局跨域)
@Configuration publicclassCorsConfigimplementsWebMvcConfigurer{ @Override publicvoidaddCorsMappings(CorsRegistryregistry){ registry.addMapping("/**") //是否發(fā)送Cookie .allowCredentials(true) //放行哪些原始域 .allowedOrigins("*") .allowedMethods(newString[]{"GET","POST","PUT","DELETE"}) .allowedHeaders("*") .exposedHeaders("*"); } }
3. 使用注解 (局部跨域)
在控制器(類上)上使用注解 @CrossOrigin:,表示該類的所有方法允許跨域。
@RestController @CrossOrigin(origins="*") publicclassHelloController{ @RequestMapping("/hello") publicStringhello(){ return"helloworld"; } }
在方法上使用注解 @CrossOrigin:
@RequestMapping("/hello") @CrossOrigin(origins="*") //@CrossOrigin(value="http://localhost:8081")//指定具體ip允許跨域 publicStringhello(){ return"helloworld"; }
4. 手動(dòng)設(shè)置響應(yīng)頭(局部跨域)
使用 HttpServletResponse 對象添加響應(yīng)頭(Access-Control-Allow-Origin)來授權(quán)原始域,這里 Origin的值也可以設(shè)置為 “*”,表示全部放行。
@RequestMapping("/index") publicStringindex(HttpServletResponseresponse){ response.addHeader("Access-Allow-Control-Origin","*"); return"index"; }
5. 使用自定義filter實(shí)現(xiàn)跨域
首先編寫一個(gè)過濾器,可以起名字為MyCorsFilter.java
packagecom.mesnac.aop; importjava.io.IOException; importjavax.servlet.Filter; importjavax.servlet.FilterChain; importjavax.servlet.FilterConfig; importjavax.servlet.ServletException; importjavax.servlet.ServletRequest; importjavax.servlet.ServletResponse; importjavax.servlet.http.HttpServletResponse; importorg.springframework.stereotype.Component; @Component publicclassMyCorsFilterimplementsFilter{ publicvoiddoFilter(ServletRequestreq,ServletResponseres,FilterChainchain)throwsIOException,ServletException{ HttpServletResponseresponse=(HttpServletResponse)res; response.setHeader("Access-Control-Allow-Origin","*"); response.setHeader("Access-Control-Allow-Methods","POST,GET,OPTIONS,DELETE"); response.setHeader("Access-Control-Max-Age","3600"); response.setHeader("Access-Control-Allow-Headers","x-requested-with,content-type"); chain.doFilter(req,res); } publicvoidinit(FilterConfigfilterConfig){} publicvoiddestroy(){} }
在web.xml中配置這個(gè)過濾器,使其生效
CorsFilter com.mesnac.aop.MyCorsFilter CorsFilter /*
審核編輯:劉清
-
控制器
+關(guān)注
關(guān)注
114文章
17098瀏覽量
184186 -
JAVA語言
+關(guān)注
關(guān)注
0文章
138瀏覽量
20692 -
過濾器
+關(guān)注
關(guān)注
1文章
439瀏覽量
20379 -
CORS
+關(guān)注
關(guān)注
1文章
7瀏覽量
9045
原文標(biāo)題:Spring Boot 實(shí)現(xiàn)跨域的 5 種方式,總有一種適合你,建議收藏
文章出處:【微信號:芋道源碼,微信公眾號:芋道源碼】歡迎添加關(guān)注!文章轉(zhuǎn)載請注明出處。
發(fā)布評論請先 登錄
多位寬數(shù)據(jù)通過握手方式跨時(shí)鐘域

Spring Boot如何實(shí)現(xiàn)異步任務(wù)
啟動(dòng)Spring Boot項(xiàng)目應(yīng)用的三種方法
Spring Boot嵌入式Web容器原理是什么
Spring Boot從零入門1 詳述
「Spring認(rèn)證」什么是Spring GraphQL?

Spring Boot特有的實(shí)踐
Spring Boot Web相關(guān)的基礎(chǔ)知識
Spring Boot中整合兩種定時(shí)任務(wù)的方法

Spring Boot如何優(yōu)雅實(shí)現(xiàn)數(shù)據(jù)加密存儲、模糊匹配和脫敏

Spring Boot Actuator快速入門
Spring Boot啟動(dòng) Eureka流程

Spring Boot的啟動(dòng)原理

Spring Boot 的設(shè)計(jì)目標(biāo)

評論