由于CORS(跨域)本身是具有安全隱患的所灸,因此瀏覽器默認(rèn)是禁止的荧琼。但跨域卻在web開發(fā)中具有很重要的作用譬胎,也是前端dev經(jīng)常為之頭痛的領(lǐng)域。那么命锄,前端到底如何跨這個域呢堰乔,且往下看。
前端常見的跨域手段如下:
1.script/link/img加載外部資源
一個網(wǎng)站常常會加載以下外部資源:
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js"></script>
<link rel="stylesheet" >
<img src=“http://www.otherdomain.com/apple.jpg” />
它們都有一個相似的特點脐恩,即js運行時一般很難去獲取其加載的資源內(nèi)容浩考。具體來說,有時候我們經(jīng)常需要請求類似http://www.otherdomain.com/data.json
的文件被盈,那我們?nèi)绾文軌颢@取這個文件的內(nèi)容呢析孽?
2.發(fā)送ajax
面對上面的問題,大多數(shù)人就會說“發(fā)送ajax請求啊”只怎,具體實現(xiàn)如下:
$.get(‘/data.json’,function(res) {…});
可是不好意思親袜瞬,你這是同源的,當(dāng)然能請求到了身堡。如果你訪問的是http://www.otherdomain.com/data.json
,那么一定會報錯邓尤,提示你不允許跨域。
其實仔細想想也不難理解贴谎,別人站點上的資源你可以通過瀏覽器打開訪問汞扎,這沒問題,因為你是處在當(dāng)前的站點訪問當(dāng)前的資源擅这;但是如果你在自己的站內(nèi)去請求別人的資源澈魄,還能隨隨便便請求到的話,是你你愿意不仲翎?
所以痹扇,如果你利用ajax請求到了外部資源,只有一種情況:被訪問的server端允許你跨域溯香,即:
jsonp(返回script后調(diào)用前端方法)
后端在response header中設(shè)置了Allow-Control-Allow-Origin: matcher(例如鲫构,
*
)
3.利用iframe
其實很容易想到,iframe本身是一個html tag
玫坛,那么它和其他能夠加載資源的tag
類似结笨,肯定也能加載外部頁面,從這一點來說它算跨域。
但有一個很重要的前提:如果加載的iframe是一個外部頁面炕吸,并且你無法修改這個頁面本身(比如某個站點的首頁)伐憾,那么你只能在iframe里去操作其加載的頁面。換言之算途,如果你想在主頁面內(nèi)訪問嵌套的iframe內(nèi)容塞耕,那同樣還是有安全問題蚀腿,是會被禁止的嘴瓤。
對于這種情況的處理,就得說說postMessage了莉钙。我們知道廓脆,頁面內(nèi)嵌套頁面是會形成window鏈的,即top->parent->...磁玉,而postMessage可以實現(xiàn)不同window之間的消息傳遞停忿。
假設(shè)A頁面和B頁面屬于不同的domain,A中的iframe加載了B蚊伞,那么用postMessage通信的方式如下:
- 在B中添加消息監(jiān)聽事件
window.addEventListener(‘message’, function(e){ … });
- 在A頁面里找到B的window后調(diào)用postMessage發(fā)送數(shù)據(jù)
window.frames[0].postMessage(’some data’, '*');
可以看到B其實已經(jīng)知道自己需要跨域席赂,所以向A暴露了事件作為間接操作dom的接口,進行了自發(fā)自收的通信方式时迫。所以只有當(dāng)我們有權(quán)限修改所加載的外部頁面時颅停,postMessage才行得通。
到此掠拳,基本可以得出結(jié)論癞揉,如果在極端情況(只有前端,無法修改后端溺欧,無法修改外部資源喊熟,只有一個外部api或者url)下,前端是不能跨域的姐刁,這是瀏覽器的限制芥牌。
任性就是想跨域
那么也不是沒有辦法:我們可以修改瀏覽器的設(shè)置,取消瀏覽器對跨域的限制聂使。
其實chrome extension app就允許你這么干胳泉,開發(fā)extension時,在mainfest.json
里岩遗,如下配置你的app即可讓瀏覽器對跨域沒有任何限制:
"permissions": [
"http://*/*",
"https://*/*"
]
所以許多chrome的插件也由此誕生扇商,其中votes比較多的Allow-Control-Allow-Origin
就是一個不錯的跨域toggle工具。
可是講真的宿礁,你這么任性取消了CORS的限制案铺,那我們還聊什么跨域呢?