說說跨域那些事兒(轉載)

原文鏈接:http://itoss.me/2016/12/31/說說跨域那些事兒/

作者寄語:首先糾正一個誤區,跨域並非瀏覽器限制了發起跨站請求的這種能力,恰恰相反,我們可以發出請求,服務端也可以接收到請求並正常返回數據,只不過在返回之後瀏覽器會阻止非同源數據(response),從而在控制檯打出一系列報錯信息。
兼容性查找

文章中會涉及一系列兼容性的圖解(mdn & can i use)和一些專有名詞(mdn),可以通過兩個渠道來查看

Can I Use
MDN
什麼是跨域

定義就不說了,從字面也可以看其含義,首先我們認識下哪些情況屬於跨域,可以分爲以下幾點:

協議不同,如http, https;
端口不同;
主域相同,子域不同;
主域不同;
ip地址和域名之間也算是跨域,瀏覽器不會自動做ip域名的映射;
解決方案

document.domain
window.name
jsonp
postMessage
cors
document.domain

關鍵點
跨域分爲兩種,一種xhr不能訪問不同源的文檔,另一種是不同window之間不能進行交互操作;
document.domain主要是解決第二種情況,且只能適用於主域相同子域不同的情況;
document.domain的設置是有限制的,我們只能把document.domain設置成自身或更高一級的父域,且主域必須相同。例如:a.b.example.com中某個文檔的document.domain可以設成a.b.example.com、b.example.com 、example.com中的任意一個,但是不可以設成c.a.b.example.com,因爲這是當前域的子域,也不可以設成baidu.com,因爲主域已經不相同了。
兼容性:所有瀏覽器都支持;
優點:
可以實現不同window之間的相互訪問和操作;
缺點:
只適用於父子window之間的通信,不能用於xhr;
只能在主域相同且子域不同的情況下使用;
使用方式
a(當前頁面或父頁面)頁面中加入document.domain = ‘example.com’;
b(當前頁面或子頁面)頁面中加入document.domain = ‘example.com’;
a頁面訪問b頁面裏面的數據或者方法;
window.name

關鍵點:window.name在頁面的生命週期裏共享一個window.name;
兼容性:所有瀏覽器都支持;
優點:
最簡單的利用了瀏覽器的特性來做到不同域之間的數據傳遞;
不需要前端和後端的特殊配製;
缺點:
大小限制:window.name最大size是2M左右,不同瀏覽器中會有不同約定;
安全性:當前頁面所有window都可以修改,很不安全;
數據類型:傳遞數據只能限於字符串,如果是對象或者其他會自動被轉化爲字符串,如下;
window.name非字符串測試
使用方式:修改window.name的值即可;
jsonp

關鍵點:瀏覽器對XHR做了同源策略,但並沒有將這種方式延續到script上(其實還有iframe,img等),從而可以利用動態script標籤技術來做到跨域請求的作用。至於爲什麼會這樣設計,本人也不太清楚,有可能是歷史遺蹟(漏洞),有可能是某些方面的技術瓶頸,也有可能是爲了滿足某些需求專門定製的,總之這項技術方案我們過去可以用,現在可以用就ok,至於將來應該也是會存在的,畢竟現在已經應用在很多家站點上,就算會廢棄,也會有一段時間迭代。
兼容性:所有瀏覽器都兼容這種方式;
優點:很明顯前端可以很輕鬆的做到跨域請求;
缺點
只能通過GET方式請求,一方面是參數長度有限制,二是安全性比較差;
後端需要知道前端的cb是什麼樣的結構,主要在參數和回調名;
後端需要進行參數和cb的拼接然後才能執行;
使用方式
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
/* 前端生成script標籤,並將src中傳入需要執行的callback */

var ele = document.createElement('script'); ele.type = "text/javascript" ele.src = "http://example.com?jsonp=cb"; document.body.appendChild(ele);

/* 後端接到參數後給callback加入參數並執行 */

發佈了25 篇原創文章 · 獲贊 10 · 訪問量 15萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章