您好,登錄后才能下訂單哦!
本篇內(nèi)容主要講解“SpringBoot中的跨域問題怎么解決”,感興趣的朋友不妨來看看。本文介紹的方法操作簡(jiǎn)單快捷,實(shí)用性強(qiáng)。下面就讓小編來帶大家學(xué)習(xí)“SpringBoot中的跨域問題怎么解決”吧!
當(dāng)一個(gè)請(qǐng)求url的協(xié)議、域名、端口三者之間任意一個(gè)與當(dāng)前頁面url不同即為跨域。
出于安全原因,瀏覽器禁止Ajax調(diào)用駐留在當(dāng)前原點(diǎn)之外的資源,比如從a.com發(fā)送一個(gè)ajax請(qǐng)求到b.com,則瀏覽器控制臺(tái)會(huì)報(bào)跨域訪問錯(cuò)誤。
如下圖,從http://localhost:63342/
站點(diǎn)頁面中向ttp://localhost:8080/chat21/cors/test2
發(fā)送一個(gè)ajax請(qǐng)求,則出現(xiàn)了紅色的錯(cuò)誤信息,錯(cuò)誤中包含了Access-Controll-Allow-Origin
這樣字樣的錯(cuò)誤,以后看到這個(gè)的時(shí)候,大家就要一眼看出來這是跨域問題。
同源策略是瀏覽器的一個(gè)重要的安全策略,它用于限制一個(gè)源的文檔或其加載的腳本如何與另外一個(gè)源進(jìn)行交互,它能夠隔絕惡意文檔,減少被攻擊的媒介。
如果兩個(gè)URL的協(xié)議、主機(jī)名和端口號(hào)都是相同的,那么這兩個(gè)URL就是同源的,否則不同源,不同源的訪問就會(huì)出現(xiàn)跨域問題,就會(huì)出現(xiàn)上面的錯(cuò)誤。
下表給出了與 URL http://store.company.com/dir/page.html
的源進(jìn)行對(duì)比的示例:
URL | 結(jié)果 | 原因 |
---|---|---|
http://store.company.com/dir2/other.html | 同源 | 只有路徑不同 |
https://store.company.com/secure.html | 非同源 | 協(xié)議不同 |
http://store.company.com:81/dir/etc.html | 非同源 | 端口號(hào)不同 |
http://news.company.com/dir/other.html | 非同源 | 主機(jī)名不同 |
也就是說當(dāng)在http://store.company.com/dir/page.html
這個(gè)網(wǎng)站中向https://store.company.com
、http://store.company.com:81
和http://news.company.com
三個(gè)地址發(fā)起AXJX
請(qǐng)求都會(huì)失敗并且會(huì)報(bào)跨域的錯(cuò)誤。這就是瀏覽器的同源策略,只能訪問同源的數(shù)據(jù)。
跨域問題需要使用CORS來解決,請(qǐng)求端和后端接口需要遵循CORS規(guī)則來通信,便可解決跨域訪問的問題。
CORS全稱Cross-Origin Resource Sharing, 即跨域資源共享,是一個(gè)由一系列HTTP頭組成的系統(tǒng),這些HTTP頭決定瀏覽器是否阻止前端javascript代碼獲取跨域請(qǐng)求的響應(yīng)。為什么需要CORS ?這是因?yàn)闉g覽器存在同源安全策略,當(dāng)我們?cè)诋?dāng)前域請(qǐng)求另外一個(gè)域的資源時(shí),瀏覽器默認(rèn)會(huì)阻止腳本讀取它的響應(yīng),這時(shí)CORS就有了用武之地。
跨源資源共享(CORS)是由大多數(shù)瀏覽器實(shí)現(xiàn)的W3C規(guī)范,允許您靈活地指定什么樣的跨域請(qǐng)求被授權(quán),而不是使用一些不太安全和不太強(qiáng)大的策略,如IFRAME或JSONP等。
CORS的原理:簡(jiǎn)單點(diǎn)說,就是在請(qǐng)求頭或響應(yīng)頭中添加了一些配置,通過這些配置來便可輕松解決跨域問題。
想詳細(xì)了解CORS原理的,建議先閱讀下面2篇文章,然后再繼續(xù)向下看,否則,最后你知道SpringMVC是如何解決的,但是不知道本質(zhì)的原理是什么。
CORS通信:http://itsoku.com/article/197
瀏覽器安全策略 & CORS:http://itsoku.com/article/198
SpringMVC內(nèi)部提供了跨域問題的解決方案,只需要做一些簡(jiǎn)單的配置,而接口基本上不用做任何修改,便可解決跨域問題。
SpringMVC解決跨域問題的原理也就是SpringMVC遵循了CORS通信的規(guī)則來解決了跨域的問題,在響應(yīng)頭中添加了一些CORS需要的信息。
SpringMVC中提供了3種方案來解決跨域問題,下面一起來了解下。
接口方法上標(biāo)注org.springframework.web.bind.annotation.CrossOrigin
注解,如下test1接口上標(biāo)注了@CrossOrigin
注解,這個(gè)接口就支持跨域訪問,@CrossOrigin注解中含有更詳細(xì)的配置,這里就不細(xì)說了
也可以在類上標(biāo)注@CrossOrigin
注解,那么這個(gè)類中所有接口會(huì)支持跨域訪問
也可同時(shí)在類和方法上標(biāo)注@CrossOrigin
注解,最后方法上的跨域訪問會(huì)取合并后的配置
@RestController public class CorsController { @RequestMapping("/cors/test1") @CrossOrigin public List<String> test1() { List<String> result = Arrays.asList("www.itsoku.com", "Spring高手系列", "SpringMVC系列", "MySQL系列", "高并發(fā)系列"); return result; } }
除了細(xì)粒度、基于注釋的配置之外,您還可能需要定義一些全局CORS配置,這類似于使用篩選器,但可以聲明為Spring MVC并結(jié)合細(xì)粒度@CrossOrigin配置。默認(rèn)情況下,所有origins and GET, HEAD and POST methods是允許的。
@EnableWebMvc @Configuration public class MvcConfig implements WebMvcConfigurer { @Override public void addCorsMappings(CorsRegistry registry) { //每次調(diào)用registry.addMappin可以添加一個(gè)跨域配置,需要多個(gè)配置可以多次調(diào)用registry.addMapping registry.addMapping("/**") .allowedOrigins("*") //放行哪些原始域 .allowedMethods("PUT", "DELETE","POST", "GET") //放行哪些請(qǐng)求方式 .allowedHeaders("header1", "header2", "header3") //放行哪些原始請(qǐng)求頭部信息 .exposedHeaders("header1", "header2") //暴露哪些頭部信息 .allowCredentials(false) //是否發(fā)送 Cookie .maxAge(3600); // Add more mappings... } }
//處理跨域的Filter //1. 添加 CORS配置信息 CorsConfiguration config = new CorsConfiguration(); //放行哪些原始域 config.addAllowedOrigin("*"); //是否發(fā)送 Cookie config.setAllowCredentials(false); //放行哪些請(qǐng)求方式 config.addAllowedMethod("*"); //放行哪些原始請(qǐng)求頭部信息 config.addAllowedHeader("*"); //暴露哪些頭部信息 config.addExposedHeader("*"); //2. 添加映射路徑 UrlBasedCorsConfigurationSource corsConfigurationSource = new UrlBasedCorsConfigurationSource(); corsConfigurationSource.registerCorsConfiguration("/**",config);
git地址:https://gitee.com/javacode2018/springmvc-series
CorsController中有2個(gè)接口,第一個(gè)接口上標(biāo)注了@CrossOrigin注解,可以解決跨域訪問的問題,而第二個(gè)方法沒有標(biāo)注。
@RestController public class CorsController { @RequestMapping("/cors/test1") @CrossOrigin public List<String> test1() { List<String> result = Arrays.asList("www.itsoku.com", "Spring高手系列", "SpringMVC系列", "MySQL系列", "高并發(fā)系列"); return result; } @RequestMapping("/cors/test2") public List<String> test2() { List<String> result = Arrays.asList("www.itsoku.com", "Spring高手系列", "SpringMVC系列", "MySQL系列", "高并發(fā)系列"); return result; } }
靜態(tài)頁面cors.html中添加了2個(gè)按鈕,點(diǎn)擊2個(gè)按鈕的時(shí)候,分別以ajax跨域的方式訪問上面2個(gè)接口,第1個(gè)按鈕訪問第一個(gè)接口,第2個(gè)按鈕訪問第二個(gè)接口,然后在瀏覽器控制臺(tái)查看效果。
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>cors</title> <script type="text/javascript" src="jquery-3.6.0.min.js"></script> <script type="text/javascript"> $(function () { $("#cors-btn1").click(function () { $.ajax({ url: "http://localhost:8080/chat21/cors/test1", success: function (data) { console.log(JSON.stringify(data)); } }); }); $("#cors-btn2").click(function () { $.ajax({ url: "http://localhost:8080/chat21/cors/test2", success: function (data) { console.log(JSON.stringify(data)); } }); }); }) </script> </head> <body> <button id="cors-btn1">跨域測(cè)試test1</button> <button id="cors-btn2">跨域測(cè)試test2</button> </body> </html>
在idea中選中cors.html,然后鼠標(biāo)右鍵->Run,即可運(yùn)行
運(yùn)行效果如下(最好以chrome瀏覽器運(yùn)行),idea中支持直接運(yùn)行靜態(tài)頁面,大家注意這里的端口是63342,而上面tomcat的端口是8080,然后瀏覽器中按F12打開瀏覽器控制臺(tái),選中Console選項(xiàng)卡,稍后在這里可以看到點(diǎn)擊按鈕驗(yàn)證跨域的效果。
再看看下面這個(gè)圖,正常的跨域請(qǐng)求,響應(yīng)頭多了幾個(gè)頭,主要是Access-Control開頭的頭是和CORS相關(guān)的,瀏覽器就是根據(jù)這些響應(yīng)頭來決定跨域訪問是不是正常的,如果沒有這些頭,瀏覽器將拒絕讀取響應(yīng)體,然后就報(bào)錯(cuò)啦。
到此,相信大家對(duì)“SpringBoot中的跨域問題怎么解決”有了更深的了解,不妨來實(shí)際操作一番吧!這里是億速云網(wǎng)站,更多相關(guān)內(nèi)容可以進(jìn)入相關(guān)頻道進(jìn)行查詢,關(guān)注我們,繼續(xù)學(xué)習(xí)!
免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。