出于安全方面的考慮,瀏覽器遵從同源策略的原則。即同協議(http/https)、同域名(jianshu.com/jianshu.book.com)、同端口(jianshu.com/jianshu.com:8080)。不允許非同源的客戶端讀寫對方的文件,但是我們需要從服務器獲取數據,而服務器的地址和我們網站的地址不是總是一樣的,所以我們需要解決跨域的問題。
跨域的實現形式
常見的跨域解決方式有四種:CORS
、JSONP
、降域
和 postMessage
。
前兩種針對網頁獲取數據的解決方式,后兩種主要針對頁面內的 iframe 元素的實現方式。
CORS
CORS 的全稱為跨域資源共享(Cross-Origin Resource Sharing),是一種 ajax 跨域請求的方式,支持現代瀏覽器,IE10 以上支持。
CORS 實現跨域的原理是:當頁面使用 XMLHttpRequest 發送請求的時候,瀏覽器會自動檢查請求地址是否符合同源策略。當請求不符合同源策略時,瀏覽器會在請求頭中添加一項 Origin ,后臺會進行判斷。如果確定接受請求,則在響應頭中添加一項 Access-Control-Allow-Origin 。瀏覽器會判斷響應頭中有沒有 Access-Control-Allow-Origin 這一項;如果有,瀏覽器會處理響應,可以拿到數據;否則將會無法拿到數據。
JSONP
JSONP 是一種相對來說比較 Hack 的方法。HTML 下 script 標簽可以引入其他域下的 JS ,
利用這一點,可以實現跨域訪問,但是需要后端的接口支持。
這里將 script
標簽添加后在刪除只是為了美觀,不影響頁面整體。
實際上是用一個函數將返回的數據 ‘包裹’ 起來,將返回的數據作為參數傳入處理函數中。
JSONP(JSON with padding) 是通過 script 標簽加載數據的方式來獲取數據當作 JS 代碼來執行。提前在頁面上聲明一個函數,函數名通過接口傳參的方式傳送給后臺,后臺解析到函數名后在原始數據上 ‘包裹’ 這個函數名,發送給前端。
降域以及 postMessage
這兩種方式主要是針對頁面內 iframe 元素來進行的跨域實現。
降域
降域有一個很重要的點就是鏈接網址的后面部分一定要一樣。例如這里的 a.jianshu.com
和 b.jianshu.com
,這里的 jianshu.com
都是相同的。將 document
的 domain
屬性設置為相同部分的網址即可實現降域。
postMessage
postMessage 是將頁面內的消息作為一個 message 發送給 iframe 內的頁面,頁面內監聽 message
事件,在監聽事件內進行操作。這種跨域方式并沒有域名的限制,但是不能直接操作 iframe 內的元素,只能收到 iframe 的相應。