摘要:通過跨域通過引入的不受同源策略的限制,所以我們可以通過標簽引入一個或者是一個其他后綴形式如,等的文件,此文件返回一個函數的調用。
1.跨域的定義
只要協議、域名、端口有任何一個不同,就會被當做為不同的域,如果從A域名訪問B域名上的資源就叫做跨域。
下面我們來看下幾種跨域的方法:
2.document.domain瀏覽器的同源策略有一些限制,第一,不能通過ajax方法去請求不同源的資源;第二,瀏覽器中不同域的框架之間是不能進行JS交互的。假如有一個頁面A,地址是http://www.domain.cn/A.html,在這個頁面里有個iframe,它的地址是http://domain.cn/B.html,顯然A和B是不同域的,所以我們沒法通過JS來訪問iframe中的數據和方法。
這種情況就就可以用document.domain來解決。
解決方法就是把http://www.domain.cn/A.html和http://domain.cn/B.html的document.domain設成相同的域名,需要注意的是, 我們只能把document.domain設置成自身或更高一級的父域,且主域必須相同。
在A中我們把設置document.domain:
在B頁面中我們也設置document.domain
但是這種方法只適合不同子域的框架間的交互。
3.location.hash在一個有iframe的頁面中,父窗口可以對iframe的URL進行讀寫,iframe也可以讀寫父窗口的URL。URL有一部分#加上后面的字符可以用來進行錨點定位,這部分就是hash。利用修改URL的hash部分可以進行雙向通信,從而達到跨域的目的。每個window通過改變其他window的location來發送消息,其他窗口通過監聽URL變化的事件來接收消息。這個方式的通信會造成一些不必要的瀏覽器歷史記錄,而且有些瀏覽器不支持onhashchange事件,需要輪詢來獲知URL的改變,最后,這樣做也存在缺點,諸如數據直接暴露在了url中,數據容量和類型都有限等。下面是一個例子:
假如父頁面是baidu.com/a.html,iframe嵌入的頁面為google.com/b.html(此處省略了域名等url屬性),要實現此兩個頁面間的通信可以通過以下方法。
a.html傳送數據到b.html,a.html下修改iframe的src為:
google.com/b.html#paco
b.html監聽到url發生變化,觸發相應操作
b.html傳送數據到a.html,由于兩個頁面不在同一個域下IE、Chrome不允許修改parent.location.hash的值,所以要借助于父窗口域名下的一個代理iframe
b.html下創建一個隱藏的iframe,此iframe的src是baidu.com域下的,并掛上要傳送的hash數據,如src=”http://www.baidu.com/proxy.ht...”
proxy.html監聽到url發生變化,修改a.html的url(因為a.html和proxy.html同域,所以proxy.html可修改a.html的url hash)
a.html監聽到url發生變化,觸發相應操作
b.html的代碼:
try { parent.location.hash = "data"; } catch (e) { // ie、chrome的安全機制無法修改parent.location.hash, var ifrproxy = document.createElement("iframe"); ifrproxy.style.display = "none"; ifrproxy.src = "http://www.baidu.com/proxy.html#data"; document.body.appendChild(ifrproxy); }
proxy.html頁面的關鍵代碼如下 :
//因為parent.parent(即baidu.com/a.html)和baidu.com/proxy.html屬于同一個域,所以可以改變其location.hash的值 parent.parent.location.hash = self.location.hash.substring(1);4.通過H5的postMessage()
IE8、Chrome、Firefox、Safari、Opera等瀏覽器都支持這個方法,這個功能主要包括接收信息的方法和發送消息的postMessage方法。比如damonare.cn域的A頁面通過iframe嵌入了一個google.com域的B頁面,可以通過以下方法實現A和B的通信:
A頁面通過postMessage發送消息:
window.onload = function() { var ifr = document.getElementById("ifr"); var targetOrigin = "http://www.google.com"; ifr.contentWindow.postMessage("hello world!", targetOrigin); }
B頁面通過message事件監聽并接受消息:
var onmessage = function (event) { var data = event.data;//消息 var origin = event.origin;//消息來源地址 var source = event.source;//源Window對象 if(origin=="http://www.baidu.com"){ console.log(data);//hello world! } }; if (typeof window.addEventListener != "undefined") { window.addEventListener("message", onmessage, false); } else if (typeof window.attachEvent != "undefined") { //for ie window.attachEvent("onmessage", onmessage); }
上面幾種方式都是頁面和iframe之間或者頁面和頁面之間的,下面介紹的是單向跨域,一般用于獲取數據。
5.通過JSOP跨域通過script引入的JS不受同源策略的限制,所以我們可以通過script標簽引入一個js或者是一個其他后綴形式(如php,jsp等)的文件,此文件返回一個js函數的調用。
比如,有個a.html頁面,它里面的代碼需要利用ajax獲取一個不同域上的json數據,假設這個json數據地址是http://damonare.cn/data.php,那么a.html中的代碼就可以這樣:
因為是當做一個js文件來引入的,所以http://damonare.cn/data.php返回的必須是一個能執行的js文件,所以這個頁面的php代碼可能是這樣的,這需要和后端約定好:
最終,輸出結果為:dosomething([‘a’,’b’,’c’]);
使用jQuery封裝的JSONP方法可以很方便的進行jsonp請求:
jquery會自動生成一個全局函數來替換callback=?中的問號,之后獲取到數據后又會自動銷毀,實際上就是起一個臨時代理函數的作用。$.getJSON方法會自動判斷是否跨域,不跨域的話,就調用普通的ajax方法;跨域的話,則會以異步加載js文件的形式來調用jsonp的回調函數。
優點:不受到同源策略的影響,兼容性好,在一些古老的瀏覽器里也可以運行,不需要XMLHttpRequest或ActiveX的支持;并且在請求完畢后可以通過調用callback的方式回傳結果。
缺點:只支持GET請求,不能解決不同域的兩個頁面之間如何進行JavaScript調用的問題。
6. 通過CORS跨域CORS(Cross-Origin Resource Sharing)跨域資源共享,定義了必須在訪問跨域資源時,瀏覽器與服務器應該如何溝通。CORS背后的基本思想就是使用自定義的HTTP頭部讓瀏覽器與服務器進行溝通,從而決定請求或響應是應該成功還是失敗。目前,所有瀏覽器都支持該功能,IE瀏覽器不能低于IE10。
因此,實現CORS通信的關鍵是服務器。只要服務器實現了CORS接口,就可以跨源通信。
服務器端對于CORS的支持,主要就是通過設置Access-Control-Allow-Origin來進行的。如果瀏覽器檢測到相應的設置,就可以允許Ajax進行跨域的訪問。
CORS與JSONP的對比:
JSONP只能實現GET請求,而CORS支持所有類型的HTTP請求;
使用CORS,開發者可以使用普通的XMLHttpRequest發起請求和獲得數據,比起JSONP有
更好的錯誤處理。
CORS與JSONP相比,無疑更為先進、方便和可靠。
7.window.namewindow對象有個name屬性,該屬性有個特征:即在一個窗口(window)的生命周期內,窗口載入的所有的頁面都是共享一個window.name的,每個頁面對window.name都有讀寫的權限,window.name是持久存在一個窗口載入過的所有頁面中的,并不會因新頁面的載入而進行重置。
比如:我們在任意一個頁面輸入
window.name = "My window"s name"; setTimeout(function(){ window.location.; },1000)
進入damonare.cn頁面后我們再檢測再檢測 window.name :
window.name; // My window"s name
由于安全原因,瀏覽器始終會保持 window.name 是string 類型。
這種方法與 document.domain 方法相比,放寬了域名后綴要相同的限制,可以從任意頁面獲取 string 類型的數據。
8.反向代理服務器基礎思想很簡單,將你的服務器配置成需要 跨域獲取的資源 的反向代理服務器。
我們只需要配置nginx,在一個服務器上配置多個前綴來轉發http/https請求到多個真實的服務器即可。這樣,這個服務器上所有url都是相同的域名、協議和端口。因此,對于瀏覽器來說,這些url都是同源的,沒有跨域限制。而實際上,這些url實際上由物理服務器提供服務。這些服務器內的javascript可以跨域調用所有這些服務器上的url。
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/40546.html
摘要:前言騰訊一面,相比阿里一面來說,騰訊一面先給打電話預定時間,這也給了我們這些面試者去準備的時間。其實閉包也就是指有權訪問另一個函數作用域的函數而已。常用的創建閉包的方法就是在函數內部創建另一個函數。 前言 騰訊一面,相比阿里一面來說,騰訊一面先給打電話預定時間,這也給了我們這些面試者去準備的時間。但是也正是因為這種確定性,也有在等待電話的時候的心情的忐忑。 背景 我是一名大三學生,大一...
摘要:所謂同源是指協議域名端口三者相同,即便兩個不同的域名指向同一個地址,也非同源。那么怎樣解決跨域問題的呢通過跨域跨域跨域跨域跨域資源共享代理跨域中間件代理跨域音樂教程老師有用到協議跨域后端在頭部信息里面設置安全域名公司后端給解決過持續更新中 JavaScript篇 如何獲取瀏覽器URL中查詢字符串中的參數? 1.封裝方法 getUrlArgs(url) { const args =...
摘要:所謂同源是指協議域名端口三者相同,即便兩個不同的域名指向同一個地址,也非同源。那么怎樣解決跨域問題的呢通過跨域跨域跨域跨域跨域資源共享代理跨域中間件代理跨域音樂教程老師有用到協議跨域后端在頭部信息里面設置安全域名公司后端給解決過持續更新中 JavaScript篇 如何獲取瀏覽器URL中查詢字符串中的參數? 1.封裝方法 getUrlArgs(url) { const args =...
閱讀 2335·2023-04-25 14:29
閱讀 1457·2021-11-22 09:34
閱讀 2702·2021-11-22 09:34
閱讀 3391·2021-11-11 10:59
閱讀 1850·2021-09-26 09:46
閱讀 2221·2021-09-22 16:03
閱讀 1920·2019-08-30 12:56
閱讀 478·2019-08-30 11:12