題目1: 什么是同源策略
同源策略限制從一個源加載的文檔或腳本如何與來自另一個源的資源進(jìn)行交互。這是一個用于隔離潛在惡意文件的關(guān)鍵的安全機(jī)制。目的就是為了保證用戶信息的安全,防止惡意的網(wǎng)站竊取數(shù)據(jù)。
那什么是源呢?如果協(xié)議、域名、端口對于兩個頁面是相同的,則兩個頁面具有相同的源。
舉例來說,http://www.example.com/dir/page.html這個網(wǎng)址,協(xié)議是http://,域名是www.example.com,端口是80(默認(rèn)端口可以省略)。它的同源情況如下:
http://www.example.com/dir2/other.html:同源
http://example.com/dir/other.html:不同源(域名不同)
http://v2.www.example.com/dir/other.html:不同源(域名不同)
http://www.example.com:81/dir/other.html:不同源(端口不同)
題目2: 什么是跨域?跨域有幾種實現(xiàn)形式
當(dāng) Web 資源請求由其它域名或端口(不同源)提供的資源時,就發(fā)生了跨域請求??缬蛴袔追N實現(xiàn)形式
1.JSONP
例如我要從域A的頁面pageA加載域B的數(shù)據(jù),那么在域B的頁面pageB中我以JavaScript的形式聲明pageA需要的數(shù)據(jù),然后在 pageA中用script標(biāo)簽把pageB加載進(jìn)來,那么pageB中的腳本就會得以執(zhí)行。
function getData(data){
//這里是對獲取的數(shù)據(jù)的相關(guān)操作
console.log(data);
//數(shù)據(jù)獲取到后移除創(chuàng)建的script標(biāo)簽
document.body.removeChild(originData);
}
var originData = document.createElement('script');
originData.src = 'http://www.jesse.com/data.js';
originData.setAttribute("type", "text/javascript");
document.body.appendChild(originData);
2.CORS
跨源資源共享(CORS)定義一種跨域訪問的機(jī)制,可以讓AJAX實現(xiàn)跨域訪問。CORS允許一個域上的網(wǎng)絡(luò)應(yīng)用向另一個域提交跨域AJAX請求。實現(xiàn)此功能非常簡單,只需由服務(wù)器發(fā)送一個響應(yīng)標(biāo)頭即可。它是通過客戶端+服務(wù)端協(xié)作聲明的方式來確保請求安全的。服務(wù)端會在HTTP請求頭中增加一系列HTTP請求參數(shù)(例如Access-Control-Allow-Origin等),來限制哪些域的請求和哪些請求類型可以接受,而客戶端在發(fā)起請求時必須聲明自己的源(Orgin),否則服務(wù)器將不予處理,如果客戶端不作聲明,請求甚至?xí)粸g覽器直接攔截都到不了服務(wù)端。服務(wù)端收到HTTP請求后會進(jìn)行域的比較,只有同域的請求才會處理。
3.降域
對于主域相同而子域不同的例子,可以通過設(shè)置document.domain的辦法來解決。 具體的做法是可以在http://www.a.com/a.html和http://script.a.com/b.html兩個文件中分別加上 document.domain = "a.com";然后通過a.html文件中創(chuàng)建一個iframe,去控制iframe的contentDocument,這樣兩個js文件之間就可以 “交互”了。
4.postMessage
window.postMessage(message,targetOrigin) 方法是html5新引進(jìn)的特性,可以使用它來向其它的window對象發(fā)送消息,無論這個window對象是屬于同源或不同源,目前IE8+、FireFox、Chrome、Opera等瀏覽器都已經(jīng)支持window.postMessage方法。
題目3: JSONP 的原理是什么
就是利用<script>標(biāo)簽沒有跨域限制的“漏洞”來達(dá)到與第三方通訊的目的。當(dāng)需要通訊時,本站腳本創(chuàng)建一個<script>元素,地址指向第三方的API網(wǎng)址,形如:
<script src="http://www.example.net/api?param1=1¶m2=2"></script>
并提供一個回調(diào)函數(shù)來接收數(shù)據(jù)(函數(shù)名可約定,或通過地址參數(shù)傳遞)。
第三方產(chǎn)生的響應(yīng)為json數(shù)據(jù)的包裝(故稱之為jsonp,即json padding),形如:
callback({"name":"hax","gender":"Male"})
這樣瀏覽器會調(diào)用callback函數(shù),并傳遞解析后json對象作為參數(shù)。本站腳本可在callback函數(shù)里處理所傳入的數(shù)據(jù)。
題目4: CORS是什么
1、CORS是一個W3C標(biāo)準(zhǔn),全稱是"跨域資源共享"(Cross-origin resource sharing)。它允許瀏覽器向跨源服務(wù)器,發(fā)出XMLHttpRequest請求,從而克服了AJAX只能同源使用的限制。
2、瀏覽器將CORS請求分成兩類:簡單請求(simple request)和非簡單請求(not-so-simple request)。
(1)對于簡單請求,瀏覽器直接發(fā)出CORS請求。具體來說,就是在頭信息之中,增加一個Origin字段。
(2)非簡單請求是對服務(wù)器有特殊要求的請求,比如請求方法是PUT或DELETE,或者Content-Type字段的類型是application/json。非簡單請求的CORS請求,會在正式通信之前,增加一次HTTP查詢請求,稱為"預(yù)檢"請求(preflight),"預(yù)檢"請求用的請求方法是OPTIONS。瀏覽器先詢問服務(wù)器,當(dāng)前網(wǎng)頁所在的域名是否在服務(wù)器的許可名單之中,以及可以使用哪些HTTP動詞和頭信息字段。只有得到肯定答復(fù),瀏覽器才會發(fā)出正式的XMLHttpRequest請求,否則就報錯。