上一篇中提到過的同源策略,作為其一部分,XMLHttpRequest 對象通常只是用于發(fā)起和文檔具有相同服務(wù)器的HTTP請求。這個限制關(guān)閉了安全漏洞,但在另一方面卻阻止了大量合適使用的跨域請求。
例如,在 <form> 和 <iframe> 元素中使用跨域 URL,瀏覽器會顯示最終的跨域文檔,與此同時,瀏覽器卻不允許我們使用原始腳本查找跨域文檔的內(nèi)容,根源在于同源策略。如何做到既保證瀏覽器的安全,又要完成跨域呢?
JSONP
<script>元素并未真正受限于同源策略:它加載并執(zhí)行任何來源的腳本,只須設(shè)置<script>元素的src屬性,一旦這個元素插入到文檔中,瀏覽器就會發(fā)送一個HTTP請求以下載src屬性所指向的 URL。之后,包含JSON編碼數(shù)據(jù)的響應(yīng)體會自動解碼(即,執(zhí)行)
響應(yīng)的JSON解碼數(shù)據(jù),形如[1, 2, {"buckle": "my shoe"}]
將其包裹在一個函數(shù)名內(nèi),handleResponse([1, 2, {"buckle": "my shoe"}])
若此時有一個名為handleResponse的函數(shù),則相當于將響應(yīng)的編碼數(shù)據(jù)作為參數(shù),執(zhí)行函數(shù),為做到這點,需要前后端約定函數(shù)名,以上便是JSONP的關(guān)鍵-
CORS
CORS 全名為Cross-Origin Resource Sharing,跨域資源共享,這種請求與傳統(tǒng)的 Ajax 請求沒有區(qū)別,瀏覽器一旦發(fā)現(xiàn)Ajax請求跨域,就會自動在請求的頭部添加一些信息,若服務(wù)器實現(xiàn)了CORS接口,瀏覽器就能接收到返回的消息,實現(xiàn)跨域通信- 請求的方法
- HEAD
- GET
- POST
- HTTP的頭信息不超過以下幾種字段
- Accept
- Accept-Language
- Content-Language
- Ladt-Event-ID
- Content-type:只限于三個值 application/x-www-form-urlencoded、multipart/form-date、text/plain
詳見
- 請求的方法
postMessage
window.postMessage() 方法被調(diào)用時,會在所有頁面腳本執(zhí)行完畢之后(e.g., 在該方法之后設(shè)置的事件、之前設(shè)置的timeout 事件,etc.)向目標窗口派發(fā)一個 MessageEvent 消息。 該MessageEvent
消息有四個屬性需要注意: message 屬性表示該message 的類型; data 屬性為 window.postMessage 的第一個參數(shù);origin 屬性表示調(diào)用window.postMessage()方法時調(diào)用頁面的當前狀態(tài); source 屬性記錄調(diào)用 window.postMessage()方法的窗口信息
詳見
小結(jié):不同的場景下,解決跨域會有不同的方案,研究跨域也不應(yīng)該僅僅只是為了應(yīng)付面試,背后的原理才是關(guān)鍵,jsonp用了script的不受限及腳本的立即執(zhí)行,cors涉及到HTTP請求頭,postmessage用到了window.postMessage()這個方法