先看概念,什么是跨域:協議、域名、端口中有任何一個不同,它們之間要通信就叫跨域。
情形 | 是否允許通信 |
同一域名下 | 是 |
同一域名下不同文件夾 | 是 |
同一域名、不同端口 | 否 |
同一域名、不同協議 | 否 |
域名和域名對應ip | 否 |
主域名相同、子域名不同 | 否 |
不同域名 | 否 |
常用的跨域方式有2種:CROS(跨域資源共享Cross-Origin Resource Sharing)、JSONP
CROS:服務器端對於CORS
的支持,主要就是通過設置Access-Control-Allow-Origin
來進行的。如果瀏覽器檢測到相應的設置,就可以允許Ajax進行跨域的訪問。該設置只被現代瀏覽器支持
JSONP:實際是對跨域行為的hack手段,實現原理和加載js是一個道理,所以只能實現get請求的jsonp.
在js中,我們直接用XMLHttpRequest
請求不同域上的數據時,是不可以的。但是,在頁面上引入不同域上的js腳本文件卻是可以的,jsonp正是利用這個特性來實現的。
CORS和JSONP對比
CORS與JSONP相比,無疑更為先進、方便和可靠。
1、 JSONP只能實現GET請求,而CORS支持所有類型的HTTP請求。 2、 使用CORS,開發者可以使用普通的XMLHttpRequest發起請求和獲得數據,比起JSONP有更好的錯誤處理。 3、 JSONP主要被老的瀏覽器支持,它們往往不支持CORS,而絕大多數現代瀏覽器都已經支持了CORS)。
通過修改document.domain來跨子域
這種方式比較適合父域名相同而子域名不同的情況,通過將document.domain修改成為相同的父域名可以實現互相通信,比如:
parent.a.com/parent.html頁面里有個iframe,iframe的src指向child.a.com/child.html,正常情況下這兩個頁面是無法實現通信的,
但是只要在parent.html和child.html里分別設置document.domain="a.com",這兩個頁面即可實現互相通信
(但要注意的是,document.domain的設置是有限制的,我們只能把document.domain設置成自身或更高一級的父域)
使用window.name來進行跨域
window
對象有個name
屬性,該屬性有個特征:即在一個窗口(window)的生命周期內,窗口載入的所有的頁面都是共享一個window.name
的,
每個頁面對window.name
都有讀寫的權限,window.name
是持久存在一個窗口載入過的所有頁面中的
使用HTML5的window.postMessage方法跨域
window.postMessage(message,targetOrigin)
方法是html5
新引進的特性,可以使用它來向其它的window
對象發送消息,
無論這個window對象是屬於同源或不同源,目前IE8+、FireFox、Chrome、Opera
等瀏覽器都已經支持window.postMessage
方法。