題目1: 什么是同源策略
瀏覽器出于安全方面的考慮尊搬,只允許與本域下的接口交互扛或。不同源的客戶端腳本在沒(méi)有明確授權(quán)的情況下洲劣,不能讀寫(xiě)對(duì)方的資源泊脐。
http://a.jrg.com:8080/1.http: 指協(xié)議亚再,其他協(xié)議有https\file\ftp\ssh\mailto\tel等2.a.jrg.com: 指域名3.8080: 指端口,默認(rèn)端口號(hào)為80晨抡,若為80一般就不寫(xiě)出來(lái)了
只要協(xié)議氛悬、域名、端口有任何一個(gè)不同耘柱,都會(huì)被當(dāng)作是不同的域如捅。
同源舉例:http://jrg.com/a/b.js 和 http://jrg.com/index.php
不同源舉例:http://me.com/main.js 和 https://me.com/a.php (協(xié)議不同)
http://a.me.com/main.js 和 http://b.me.com/a.php (域名不同,域名必須完全相同才可以)
http://me.com/main.js 和 http://me.com:8080/a.php (端口不同调煎,第一個(gè)是80)
需要注意: 對(duì)于當(dāng)前頁(yè)面來(lái)說(shuō)頁(yè)面存放的 JS 文件的域不重要镜遣,重要的是加載該 JS 頁(yè)面所在什么域
題目2: 什么是跨域?跨域有幾種實(shí)現(xiàn)形式
跨域就是突破同源策略的限制士袄,去不同的域下訪問(wèn)數(shù)據(jù)
- JSONP (實(shí)際就是以加載js的方式悲关,執(zhí)行拿到不同域名中的數(shù)據(jù))
- CORS (在后端的返回頭部設(shè)置Access-Control-Allow-Origin添加允許訪問(wèn)的域名)
- 降域 (2者都設(shè)置document.domain=" "訪問(wèn)的前后都要降域并且2者都要有同一個(gè)基礎(chǔ)域名,比如a.jrg.com和b.jrg.com娄柳,降域后都為jrg.com)
- postMessage 在兩個(gè)窗口/frames間發(fā)送數(shù)據(jù)信息寓辱,但不是瀏覽器跟服務(wù)器之間交互,而是在兩個(gè)客戶端之間通信
題目3: JSONP 的原理是什么
由于同源策略赤拒,XMLHttpRequest()對(duì)象無(wú)法跨域秫筏,但<script>、<img>挎挖、<link>等標(biāo)簽是可以跨域的这敬。所以可以利用<script>標(biāo)簽來(lái)向服務(wù)器發(fā)送請(qǐng)求。
- 通過(guò)script標(biāo)簽引入一個(gè)js文件蕉朵,在src中傳遞一個(gè)callback=function參數(shù)給服務(wù)端
- 服務(wù)端返回?cái)?shù)據(jù)時(shí)會(huì)將這個(gè)callback參數(shù)作為函數(shù)名包裹住JSON數(shù)據(jù)function([json數(shù)據(jù)])
-
當(dāng)這個(gè)js文件載入成功后就會(huì)執(zhí)行我們指定的function回調(diào)函數(shù)崔涂,并且會(huì)把我們需要的JSON數(shù)據(jù)作為參數(shù)傳入
前端
服務(wù)后端
題目4: CORS是什么
跨域資源共享(Cross-origin resource sharing),是一種ajax跨域請(qǐng)求資源的方式(支持現(xiàn)代瀏覽器始衅,IE支持10以上)冷蚂。
實(shí)現(xiàn)方式:當(dāng)使用 XMLHttpRequest發(fā)送請(qǐng)求時(shí)缭保,瀏覽器發(fā)現(xiàn)該請(qǐng)求不符合同源策略,會(huì)給該請(qǐng)求加一個(gè)請(qǐng)求頭:Origin帝雇,后臺(tái)進(jìn)行一系列處理,如果確定接受請(qǐng)求則在返回結(jié)果中加入一個(gè)響應(yīng)頭:Access-Control-Allow-Origin; 瀏覽器判斷該相應(yīng)頭中是否包含 Origin的值蛉拙,如果有則瀏覽器會(huì)處理響應(yīng)尸闸,我們就可以拿到響應(yīng)數(shù)據(jù),如果不包含瀏覽器直接駁回孕锄,這時(shí)我們無(wú)法拿到響應(yīng)數(shù)據(jù)吮廉。
所以 CORS 的表象是讓你覺(jué)得它與同源的 ajax 請(qǐng)求沒(méi)啥區(qū)別,代碼完全一樣畸肆。
比如發(fā)送了一個(gè)origin頭部:
Origin: http://a.jrg.com:8080
如果服務(wù)器(后端)認(rèn)為這個(gè)請(qǐng)求可以接受宦芦,就在Access-Control-Allow-Origin頭部中發(fā)回相同的源信息:
Access-Control-Allow-Origin: http://a.jrg.com:8080 (與請(qǐng)求相同)
題目5: 根據(jù)視頻里的講解演示三種以上跨域的解決方式 ,寫(xiě)成博客
JSONP方法:
返回結(jié)果為:
cors
在服務(wù)端發(fā)送數(shù)據(jù)之前添加一個(gè)響應(yīng)頭轴脐,允許該域名跨域獲取數(shù)據(jù)
降域
當(dāng)a.jrg.com 想要操作 b.jrg.com的文件调卑,可以通過(guò)兩者都添加document.domain = "jrg.com"降域?yàn)閖rg.com才能互相操作
缺點(diǎn):只能用于相同的父級(jí)域名
PostMessage
postMessage的原理是會(huì)向另一個(gè)地方發(fā)送信息,另一個(gè)地方通常是iframe或者是由當(dāng)前頁(yè)面彈出的窗口大咱。
當(dāng)父級(jí)頁(yè)面里包含了不同域里的iframe恬涧,可以通過(guò)這種方式來(lái)進(jìn)行通信
當(dāng)父級(jí)頁(yè)面可以通過(guò)postMessgae將內(nèi)容發(fā)送給子iframe〔杲恚可以通過(guò)監(jiān)聽(tīng)message事件溯捆,來(lái)獲取信息。
window.frames[0].postMessage(value,'*')
window.addEventListener('message',function(e) {
console.log(e.data);
});
iframe可以通過(guò)postMessgae將內(nèi)容發(fā)送給父頁(yè)面厦瓢√嶙幔可以通過(guò)監(jiān)聽(tīng)message事件,來(lái)獲取信息煮仇。
window.parent.postMessage(value,'*')
window.addEventListener('message',function(e) {
console.log(e.data);
});