1. 前言
跨域,一個老生常談的話題,不管前端后端,跨域都會遇到。而今天,我就跟大家分享一篇關于【跨域】的文章,希望能給大家帶來點不一樣的收獲。
2. 環境說明
js復制代碼環境說明:windows10 + Idea2021.3.2 + Jdk1.8 + SpringBoot 2.3.1.RELEASE
3. 什么是跨域?
首先,請問大家個問題,什么是跨域?估計很多小伙伴都會這么回答,跨域不就是只要請求的 url 不同,就會造成跨域,沒錯,是這樣的,可否具體點?
所謂跨域,其實就好比這樣,A端向B端發送請求,若B端的地址協議、域名、端口三者之間任意一個與A端的址協議、域名、端口中的一個不同,這兩者訪問就跨域了。
給大家舉幾個跨域的例子,輔助大家理解。
1.http://localhost:8080/ -> http://localhost:9090/ 跨域原因:端口號不同。
2.http://10.10.10.10:8080/ -> http://20.20.20.20:8080/ 跨域原因:主機ip(域名)不同。
3.http://localhost:8080/ -> https://localhost:8080/ 跨域原因:域名不同(http/https)。
4.www.test.com/ -> test.test.com/ 跨域原因:子域名不同。
4. 為什么會跨域?
既然清楚了跨域概念,那你們知道為何會出現跨域嘛?這其實就得從瀏覽器層出發了。之所以會產生跨域,就是由于瀏覽器的同源策略,瀏覽器對JAVAscript施加的一種安全限制。
所謂同源策略,可以看成是一種約定,它是瀏覽器最核心也是最基本的安全功能,如果缺少了同源策略,則瀏覽器的正常功能都可能會受到影響。可以說Web是構建在同源策略基礎之上的,瀏覽器只是針對同源策略的一種實現。同源策略會阻止一個域的。JavaScript腳本和另外一個域的內容進行交互。所謂同源(即指在同一個域)就是兩個頁面具有相同的協議,域名和端口。
5. 如何解決跨域?
當我們對跨域概念有一定的基礎認知之后,我們就應該要學習如何解決跨域這種問題,你知道跨域,但你如果不會處理跨域,那就很掉身份啦,因為解決跨域的方式很多很多,你只需要知道常用的幾種處理方式就好了,又不是讓自己都得掌握,對吧。
所以,接下來,我給大家諾列了解決跨域的一些方法,不要求大家都能掌握,但好歹知道這種方式能處理跨域即可。具體如下:
1.改發jsonp
利用的是 script 標簽 src 屬性請求 js 無跨域問題,但具有局限性,只能發送 get 請求.
2.跨域資源共享(CORS)
CORS是一個W3C標準,全稱是"跨域資源共享",它允許瀏覽器向跨源服務器發出XMLHttpRequest請求,從而解決了ajax只能同源使用的限制。但CORS需要瀏覽器和服務器都同時支持。目前,所有瀏覽器都支持該功能;支持各種方式請求(post,get....)。
3.Nginx代理跨域
將不同的協議、域名、端口代理到與目標url一致的處理方式。
4.nodejs中間件代理跨域
在本地啟一個nodeis服務器轉接代理,前端請求本地服務器,可在自己代碼中設置跨域可訪問,而后端轉接請求后端是沒有跨域問題的(需要真實請求的地址設置可訪問才可取得數據)。
5.WebSocket協議跨域
它是一種瀏覽器的API,它的目標是在一個單獨的持久連接上提供全雙工、雙向通信。(同源策略對web sockets不適用)web sockets原理:在JS創建了web socket之后,會有一個HTTP請求發送到瀏覽器以發起連接。取得服務器響應后,建立的連接會使用HTTP升級從HTTP協議交換為web sockt協議。 只有在支持web socket協議的服務器上才能正常工作。
6. springboot跨域配置
接著,我們通過在springboot項目中配置cors,起到防止跨域的目的。由于springboot本身就支持cors,所以你只需要實現 addCorsMAppings 接口,就可以添加規則來允許跨域訪問,具體代碼如下,大家請看:
typescript復制代碼/**
* 跨域配置
*/
@Configuration
public class CorsConfig implements WebMvcConfigurer {
/**
* 跨域注冊器
*
* @param registry 跨域注冊器
*/
@Override
public void addCorsMappings(CorsRegistry registry) {
// 設置允許跨域的路徑
registry.addMapping("/**")
// 設置允許跨域請求的域名
.allowedOrigins("*")
// 是否允許證書 不再默認開啟
.allowCredentials(true)
// 設置允許的方法
.allowedMethods("*")
// 設置允許的頭
.allowedHeaders("*")
// 跨域允許時間
.maxAge(3600);
}
}
通過上面的配置,我們可以看到,是火力全開啊,把所有的攔截都放開了,允許了所有的跨域域名等。你也可以單獨設置添加,比如限制只允許www.test.com的域名訪問,那你可以這么設置:
arduino復制代碼.allowedOrigins("http://www.test.com")
再比如限定只能對 /test 下的所有接口進行跨域訪問,同時只能訪問 GET 和 POST 方法,那你這樣設置即可。
arduino復制代碼registry.addMapping("/test/**") .allowedMethods("POST", "GET");
... ...
ok,以上就是我這期的全部內容啦,如果還想學習更多,你可以看看如下的往期熱文推薦哦,每天積累一個奇淫小知識,日積月累下去,你一定能成為令人敬仰的大佬。
「贈人玫瑰,手留余香」,咱們下期拜拜~~
作者:bug菌
鏈接:
https://juejin.cn/post/7233208763921858616