中文字幕精品亚洲无线码二区,国产黄a三级三级三级看三级,亚洲七七久久桃花影院,丰满少妇被猛烈进入,国产小视频在线观看网站

Web前端入門第(di) 89 問:總結 8 種跨域通信處理方案

為什(shen)么會(hui)跨域?跨域是誰附加的限制?為什(shen)么 APP 不會(hui)有跨域問(wen)題?

首先跨域問題(ti)是由于瀏(liu)覽器(qi)的同源(yuan)策略(Same-Origin Policy)導致的,基(ji)本(ben)上(shang)所有(you)瀏(liu)覽器(qi)都有(you)限制,默認情況是不(bu)允許跨域訪問的!!

APP 的(de)(de)請求(qiu)(qiu)不(bu)受(shou)瀏覽(lan)器(qi)的(de)(de)同(tong)源策略限(xian)制,所以(yi)不(bu)存在(zai)跨(kua)域(yu)。類似一個服務(wu)器(qi)像另一個服務(wu)器(qi)發(fa)起(qi)請求(qiu)(qiu)一樣,也不(bu)會受(shou)跨(kua)域(yu)影(ying)響。

想想一下(xia):如(ru)果瀏覽器(qi)沒有(you)同源(yuan)策略限制,A 網站(zhan)(zhan)可以隨意訪問(wen) B 網站(zhan)(zhan)內容,那么(me)現在 BAT 這些(xie)一線大廠還有(you)護城(cheng)河嗎?所有(you)網站(zhan)(zhan)的數據都(dou)無隱(yin)私(si)可言(yan)了,各種釣(diao)魚網站(zhan)(zhan)在瀏覽器(qi)中橫飛!!那世道...簡直太美(mei)~~

什么是同源

同源:指的(de)是協議、域名和端口都(dou)(dou)相同(tong)。任意一(yi)個不同(tong),都(dou)(dou)會觸發瀏覽器的(de)同(tong)源(yuan)策略,從而導致(zhi)跨域。

以 MDM 的一(yi)個文檔(dang)地址(zhi)為例,看看 URL 不同的組成(cheng)部(bu)分:

1

跨域解決方案

雖然(ran)默(mo)認情(qing)況下瀏覽器(qi)是不允許跨域訪問的,但通過一些配(pei)置(zhi)手(shou)段,還是能夠實現(xian)資源(yuan)共(gong)享~~

1、跨域資源共享 CORS

目前主流的跨(kua)域(yu)共(gong)享方(fang)案,由服務器配(pei)置(zhi)響應頭告訴瀏覽(lan)器是(shi)否允(yun)許跨(kua)域(yu)訪問:

// 或 * 表示所有源都可以訪問
Access-Control-Allow-Origin: //domain.com
// 允許的方法
Access-Control-Allow-Methods: GET, POST, OPTIONS
// 允許的自定義頭
Access-Control-Allow-Headers: Content-Type, Authorization
// 允許攜帶 Cookie
Access-Control-Allow-Credentials: true

2、反向代理

原理就是前(qian)端請(qing)求(qiu)同(tong)源服(fu)(fu)務器,由(you)同(tong)源服(fu)(fu)務器向跨域目標發起請(qing)求(qiu),再由(you)同(tong)源服(fu)(fu)務器返回結果(guo)給前(qian)端。繞(rao)過了瀏覽器同(tong)源策略,但需要服(fu)(fu)務器支(zhi)持,如果(guo)請(qing)求(qiu)量太大,對自己的服(fu)(fu)務器要求(qiu)很高。

比如 nginx / node 中間件 / 開發環境的 dev-server 都是(shi)這種(zhong)方式,以(yi) nginx 跨(kua)域配置為(wei)例:

location /api/ {
  proxy_pass //domain.com/;  # 需要請求的跨域目標
  proxy_set_header Host $host;
}

3、WebSocket

WebSocket 是(shi) HTML5 新(xin)增的(de)協(xie)議(yi),允(yun)許瀏覽器(qi)和服務器(qi)之間(jian)進行全雙(shuang)工通信,天然支持跨域訪問。由于是(shi)雙(shuang)向通信,所以對服務器(qi)壓(ya)力也(ye)不小。

const ws = new WebSocket('wss://domain.com');
ws.onmessage = (event) => console.log(event.data);

4、JSONP

利用 <script> 標簽,向目標服務器發起(qi)請(qing)求(qiu),目標服務器需要返回一段(duan)函(han)數(shu)調用,將數(shu)據返回給前端。缺點是僅(jin)支持 get 請(qing)求(qiu),還容易引發 XSS 攻(gong)擊!

function handleResponse(data) {
  console.log(data);
}

const script = document.createElement('script');
script.src = '//domain.com/data?callback=handleResponse';
document.head.appendChild(script);

//domain.com/data?callback=handleResponse 需要返回 JS 代(dai)碼調用函數執行:

handleResponse({ data: 'hello' });

5、postMessage

此(ci)方(fang)式一般多用于(yu) iframe 的跨域通信(xin),比如 A 網頁使(shi)用 iframe 嵌入 B 網頁,這(zhe)種情況就可(ke)以使(shi)用 postMessage 通信(xin):

發送者:

// 發送方
iframe.contentWindow.postMessage('data', '//target-domain.com');

接收者:

// 接收方
window.addEventListener('message', (event) => {
  if (event.origin !== '//source-domain.com') {
    return;
  }
  console.log(event.data);
});

不推薦的方案

瀏覽(lan)器的版本(ben)升級后,一(yi)些老(lao)舊的跨域(yu)方案被棄用,比如:

6、document.domain + iframe

在過去,如果同一個主域名,子域名不同的情況,比如:a.domain.com 和 b.domain.com 之間進行通信,可以通過設置 document.domain = 'domain.com' 來解決,但現在的(de)瀏覽器已經限制使用了(le)!!

7、window.name + iframe

此方案有一些復雜,需要一個空白的(de)同(tong)源頁面用于繞過瀏(liu)覽(lan)器的(de)同(tong)源策略,然后獲取 iframe 的(de) name 屬性值(zhi),此處有大小限制(zhi),最多 2MB 的(de)數(shu)據。

流程:

源頁面A (domainA.com) 
     ↓ 創建iframe指向代理頁面B (domainB.com)
代理頁面B (domainB.com) 
     ↓ 接收數據并存入 window.name
     ↓ 跳轉至與A同源的空白頁面C (domainA.com)
源頁面A 
     ↓ 訪問iframe的window.name獲取數據

流程圖:

2

目前項目開(kai)發基本上已經(jing)不(bu)(bu)在使用(yong)這種方式(shi),畢(bi)竟繞來繞去的,還不(bu)(bu)如一個 postMessage 跨域方案簡(jian)單。

8、location.hash + iframe

通過修改 URL Hash 實現父子 iframe 間單向數(shu)據傳輸,雖然(ran)勉(mian)強也(ye)能算作一種(zhong)跨域方案,但由于 URL 的長度限制,數(shu)據量也(ye)不能太大,實際使用中也(ye)不簡單,所以(yi)項目(mu)上也(ye)很難(nan)見到它的身影(ying)~~

流程圖:

3

寫在最后

除了文章中這 8 種跨域方案外,還有(you)一些(xie)單向數(shu)據通(tong)信的方法,比(bi)如說:

1、使用 Fetch API 的 no-cors 模式。
2、利用圖片的 src 屬性發起 GET 請求。
3、使用(yong) sendBeacon 發送分析(xi)數據。

這些方法都只能向服務器(qi)發(fa)送數據(ju),沒辦法獲得服務器(qi)的響應,所以一(yi)般(ban)多用于(yu)一(yi)些數據(ju)統計(ji),比如:百(bai)度統計(ji)、谷歌分析(xi)等(deng)等(deng)。

當然也有一些歪門邪道,比如說(shuo):修改瀏覽器的配置允許跨域,編寫瀏覽器插件支持跨域等等。

posted @ 2025-10-28 10:52  前端路引  閱讀(186)  評論(0)    收藏  舉報