同源策略有兩個限制:(1)不能經過ajax去請求不一樣源中的數據(2)瀏覽器中不一樣域的框架之間不能進行js交互php
這些限制必定程度上保證了web通訊的安全性,但也帶來了諸多不便,因此有時候咱們須要使用一些跨域方法來獲取其餘域中的數據。css
首先有必要知道什麼狀況下須要跨域,域名、端口和協議三者只要有一個不相同時,就須要跨域,其中域名包括主域和子域。
我總結了如下8種跨域的方法,前五種是隻能單向通訊,後三種能夠實現雙向通訊。html
這個是W3C出的一個標準,它容許瀏覽器向跨域服務器發送XMLHttpRequest請求,可是否成功取決於服務器。大部分瀏覽器都已經支持CORS了。前端
使用CORS來跨域和普通的AJAX對前端來講沒什麼區別,不須要作什麼額外的事,只是請求和響應頭部會有一些關於跨域的信息。html5
2.jsonpweb
json+paddingajax
原理:瀏覽器請求script資源時不受同源策略的限制,而且請求到後是當即執行的。json
作法:聲明一個全局函數,而後動態建立一個script標籤,src屬性是請求資源地址+獲取函數的字段名+函數名,服務器收到後,返回一段js代碼,給上面那個函數傳入參數,並執行,一般參數就是請求的數據。
優勢:不受瀏覽器兼容性的限制。
缺點:只能發送GET請求。須要服務器端和客戶端提早規定好。跨域
3.CSST,利用css跨域傳輸文本瀏覽器
優勢:比JSONP更安全,不須要執行跨站腳本
缺點:只有支持CSS的瀏覽器才能執行
原理:跟JSONP有些相似,利用css沒有同源限制,請求css,設置其content屬性爲請求內容便可。
4.圖像Ping
原理和jsonP,CSST相似,利用圖像沒有同源限制,請求圖像,圖像Ping多用於跟蹤用戶點擊頁面或動態廣告曝光次數。
5.經過window.name跨域
window對象有個name屬性,該屬性有個特徵:即在一個窗口(window)的生命週期內,窗口載入的全部的頁面都是共享一個window.name的,每一個頁面對window.name都有讀寫的權限,爲了安全起見它是以字符串的格式傳遞信息的,容量高達2M,他的使用方法是這樣: 首先將要傳送的信息複製給window.name屬性,而後再這個窗口下打開另外一個頁面,最後在第二個頁面中讀取window.name的值,獲得第一個頁面發送的信息。
6.設置document.domain
頁面框架之間,也就是frame和iframe之間是能夠獲取彼此的window對象的,可是不能夠獲取window的屬性和方法,只有一個html5新引入的方法例外,這個稍後再說
可是若是二者的document.domain同樣的話,就能夠獲取別的頁面的屬性和文件了,但domian的設置也是有限制的,因此這個方法也有必定限制性
7.window.postMessage方法
也是用於不一樣frame間的通訊,一個frame調用postMessage方法,傳入兩個參數,第一個是要發送的消息,第二個是接受消息的window所在的域。接受消息的窗口監聽message事件便可
8.websocket
websocket能夠在一個單獨的持久連接上提供全雙工的雙向通訊,它沒有同源限制,因此在須要雙向通訊時websocket是一個比較不錯的跨域選擇。
var ws = new WebSocket("http://aa.com/server.php"); ws.onmessage = function(event){ var data = event.data; //處理 }; var message = { time: 10, content: "我是Claiyre" }; //發送JSON格式的數據 ws.send(JSON.stringify(message)); ws.onclose = function(event){ event.wasClean //布爾值,表示連接是否已經明確地關閉 event.code //狀態碼 event.reason //緣由短語 } ws.close(); //調用後ws.readyState的值變爲2(正在關閉)