摘要:超詳細(xì)并且?guī)У目缬蛑改蟻?lái)了本文基于你了解的同源策略,并且了解使用跨域跨域的理由。使用方法就是將符合上述條件頁(yè)面的設(shè)置為同樣的二級(jí)域名。這兩個(gè)網(wǎng)站都是協(xié)議,端口都是,且二級(jí)域名都是。
超詳細(xì)并且?guī)?Demo 的 JavaScript 跨域指南來(lái)了!
本文基于你了解 JavaScript 的同源策略,并且了解使用跨域跨域的理由。
1. JSONP首先要介紹的跨域方法必然是 JSONP。
現(xiàn)在你想要獲取其他網(wǎng)站上的 JavaScript 腳本,你非常高興的使用 XMLHttpRequest 對(duì)象來(lái)獲取。但是瀏覽器一點(diǎn)兒也不配合你,無(wú)情的彈出了下面的錯(cuò)誤信息:
XMLHttpRequest cannot load http://x.com/main.dat. No "Access-Control-Allow-Origin" header is present on the requested resource. Origin "http://y.com" is therefore not allowed access.
你心里肯定會(huì)想,我難道要用后臺(tái)做個(gè)爬蟲來(lái)獲取這個(gè)數(shù)據(jù)嗎?!(;°○° )
為了避免這種蛋疼的事情發(fā)生,JSONP 就派上用場(chǎng)了。
標(biāo)簽是不受同源策略的限制的,它可以載入任意地方的 JavaScript 文件,而并不要求同源。
所以 JSONP 的理念就是,我和服務(wù)端約定好一個(gè)函數(shù)名,當(dāng)我請(qǐng)求文件的時(shí)候,服務(wù)端返回一段 JavaScript。這段 JavaScript 調(diào)用了我們約定好的函數(shù),并且將數(shù)據(jù)當(dāng)做參數(shù)傳入。
非常巧合的一點(diǎn)(其實(shí)并不是),JSON 的數(shù)據(jù)格式和 JavaScript 語(yǔ)言里對(duì)象的格式正好相同。所以在我們約定的函數(shù)里面可以直接使用這個(gè)對(duì)象。
光說(shuō)不練假把式,讓我們來(lái)看一個(gè)例子:
你需要獲取數(shù)據(jù)的頁(yè)面 index.html:
http://x.y.com/xx.js 文件內(nèi)容:
getWeather({ "城市": "北京", "天氣": "大霧" });
我們可以看到,在我們定義了 getWeather(data) 這個(gè)函數(shù)后,直接載入了 xx.js。
在這個(gè)腳本中,執(zhí)行了 getWeather 函數(shù),并傳入了一個(gè)對(duì)象。然后我們?cè)谶@個(gè)函數(shù)中將這個(gè)對(duì)象輸出到 console 中。
這就是整個(gè) JSONP 的流程。
2. document.domain使用條件:
有其他頁(yè)面 window 對(duì)象的引用。
二級(jí)域名相同。
協(xié)議相同。
端口相同。
document.domain 默認(rèn)的值是整個(gè)域名,所以即使兩個(gè)域名的二級(jí)域名一樣,那么他們的 document.domain 也不一樣。
使用方法就是將符合上述條件頁(yè)面的 document.domain 設(shè)置為同樣的二級(jí)域名。這樣我們就可以使用其他頁(yè)面的 window 對(duì)象引用做我們想做的任何事情了。(╯▔▽▔)╯
補(bǔ)充知識(shí):
x.one.example.com 和 y.one.example.com 可以將 document.domain 設(shè)置為 one.example.com,也可以設(shè)置為 example.com。
document.domain 只能設(shè)置為當(dāng)前域名的一個(gè)后綴,并且包括二級(jí)域名或以上(.edu.cn 這種整個(gè)算頂級(jí)域名)。
我們直接操刀演示,用兩個(gè)網(wǎng)站 http://wenku.baidu.com/ 和 http://zhidao.baidu.com/。
這兩個(gè)網(wǎng)站都是 http 協(xié)議,端口都是 80, 且二級(jí)域名都是 baidu.com。
打開 http://wenku.baidu.com/,在 console 中輸入代碼:
document.domain = "baidu.com"; var otherWindow = window.open("http://zhidao.baidu.com/");
我們現(xiàn)在已經(jīng)發(fā)現(xiàn)百度知道的網(wǎng)頁(yè)已經(jīng)打開了,在百度知道網(wǎng)頁(yè)的 console 中輸入以下代碼:
document.domain = "baidu.com";
現(xiàn)在回到百度文庫(kù)的網(wǎng)頁(yè),我們就可以使用百度知道網(wǎng)頁(yè)的 window 對(duì)象來(lái)操作百度知道的網(wǎng)頁(yè)了。例如:
var divs = otherWindow.document.getElementsByTagName("div");
上面這個(gè)例子的使用方法并不常見(jiàn),但是非常詳細(xì)的說(shuō)明了這種方法的原理。
這種方法主要用在控制 的情況中。
比如我的頁(yè)面(http://one.example.com/index.... :
我們?cè)?iframe.html 中使用 JavaScript 將 document.domain 設(shè)置好,也就是 example.com。
在 index.html 執(zhí)行以下腳本:
var iframe = document.getElementById("iframe"); document.domain = "example.com"; iframe.contentDocument; // 框架的 document 對(duì)象 iframe.contentWindow; // 框架的 window 對(duì)象
這樣,我們就可以獲得對(duì)框架的完全控制權(quán)了。
補(bǔ)充知識(shí)(絕對(duì)干貨):
當(dāng)兩個(gè)頁(yè)面不做任何處理,但是使用了框架或者 window.open() 得到了某個(gè)頁(yè)面的 window 對(duì)象的引用,我們可以直接訪問(wèn)的屬性有哪些?
方法 |
---|
window.blur |
window.close |
window.focus |
window.postMessage |
window.location.replace |
屬性 | 權(quán)限 |
---|---|
window.closed | 只讀 |
window.frames | 只讀 |
window.length | 只讀 |
window.location.href | 只寫 |
window.opener | 只讀 |
window.parent | 只讀 |
window.self | 只讀 |
window.top | 只讀 |
window.window | 只讀 |
我們來(lái)看以下一個(gè)場(chǎng)景:
隨意打開一個(gè)頁(yè)面,輸入以下代碼:
window.name = "My window"s name"; location.;
再檢測(cè) window.name :
window.name; // My window"s name
可以看到,如果在一個(gè)標(biāo)簽里面跳轉(zhuǎn)網(wǎng)頁(yè)的話,我們的 window.name 是不會(huì)改變的。
基于這個(gè)思想,我們可以在某個(gè)頁(yè)面設(shè)置好 window.name 的值,然后跳轉(zhuǎn)到另外一個(gè)頁(yè)面。在這個(gè)頁(yè)面中就可以獲取到我們剛剛設(shè)置的 window.name 了。
由于安全原因,瀏覽器始終會(huì)保持 window.name 是 string 類型。
這個(gè)方法也可以應(yīng)用到與 的交互上來(lái)。
我的頁(yè)面(http://one.example.com/index.... :
在 iframe.html 中設(shè)置好了 window.name 為我們要傳遞的字符串。
我們?cè)?index.html 中寫了下面的代碼:
var iframe = document.getElementById("iframe"); var data = ""; iframe.onload = function() { data = iframe.contentWindow.name; };
定睛一看,為毛線報(bào)錯(cuò)?
細(xì)心的讀者們肯定已經(jīng)發(fā)現(xiàn)了,兩個(gè)頁(yè)面完全不同源??!
由于 window.name 不隨著 URL 的跳轉(zhuǎn)而改變,所以我們使用一個(gè)暗黑技術(shù)來(lái)解決這個(gè)問(wèn)題:
var iframe = document.getElementById("iframe"); var data = ""; iframe.onload = function() { iframe.onload = function(){ data = iframe.contentWindow.name; } iframe.src = "about:blank"; };
或者將里面的 about:blank 替換成某個(gè)同源頁(yè)面(最好是空頁(yè)面,減少加載時(shí)間)。
補(bǔ)充知識(shí):
about:blank,javascript: 和 data: 中的內(nèi)容,繼承了載入他們的頁(yè)面的源。
這種方法與 document.domain 方法相比,放寬了域名后綴要相同的限制,可以從任意頁(yè)面獲取 string 類型的數(shù)據(jù)。
4. [HTML5] postMessage在 HTML5 中, window 對(duì)象增加了一個(gè)非常有用的方法:
windowObj.postMessage(message, targetOrigin);
windowObj: 接受消息的 Window 對(duì)象。
message: 在最新的瀏覽器中可以是對(duì)象。
targetOrigin: 目標(biāo)的源,* 表示任意。
這個(gè)方法非常強(qiáng)大,無(wú)視協(xié)議,端口,域名的不同。下面是烤熟的栗子:
var windowObj = window; // 可以是其他的 Window 對(duì)象的引用 var data = null; addEventListener("message", function(e){ if(e.origin == "http://jasonkid.github.io/fezone") { data = e.data; e.source.postMessage("Got it!", "*"); } });
message 事件就是用來(lái)接收 postMessage 發(fā)送過(guò)來(lái)的請(qǐng)求的。函數(shù)參數(shù)的屬性有以下幾個(gè):
origin: 發(fā)送消息的 window 的源。
data: 數(shù)據(jù)。
source: 發(fā)送消息的 Window 對(duì)象。
Demohttps://github.com/JasonKid/f...
兩種服務(wù)端相關(guān)跨域方法「JavaScript」兩種服務(wù)端相關(guān)跨域方法詳解 ← 反向代理、CORS方法請(qǐng)點(diǎn)這里
覺(jué)得不錯(cuò)的話按頂部的推薦,讓更多人看到吧~ㄟ(▔▽▔ㄟ)
文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請(qǐng)注明本文地址:http://www.ezyhdfw.cn/yun/85931.html
摘要:之前我們講了一下四種跨域的方式四種跨域方式詳解。這四種方式是使用純來(lái)進(jìn)行跨域的。今天就介紹兩種有涉及到服務(wù)器的跨域技術(shù)。 之前我們講了一下四種 JavaScript 跨域的方式 - 「JavaScript」四種跨域方式詳解。這四種方式是使用純 JavaScript 來(lái)進(jìn)行跨域的。 今天就介紹兩種有涉及到服務(wù)器的跨域技術(shù)。 一、反向代理服務(wù)器 基礎(chǔ)思想很簡(jiǎn)單,將你的服務(wù)器配置成 需要跨域...
摘要:頁(yè)面和頁(yè)面是沒(méi)有跨域的一開始我只想到用提交數(shù)據(jù)來(lái)實(shí)現(xiàn),不過(guò)一想,是直接提交到頁(yè)面嗎一時(shí)之間,我也不知道該如何進(jìn)行頁(yè)面跳轉(zhuǎn)之間的數(shù)據(jù)傳遞。參考文章利用跨域獲取數(shù)據(jù)詳解四種跨域方式詳解 先描述一下需求情景有一個(gè)生成節(jié)日賀卡的頁(yè)面,a頁(yè)面最后部分用來(lái)填寫用戶名和賀卡內(nèi)容,點(diǎn)擊提交按鈕跳轉(zhuǎn)到賀卡頁(yè)面b,b頁(yè)面顯示的就是a頁(yè)面填寫的內(nèi)容和用戶名。(a頁(yè)面和b頁(yè)面是沒(méi)有跨域的...) 一開始我只...
摘要:中的跨域請(qǐng)求應(yīng)該也算是一個(gè)重點(diǎn),具體什么叫跨域,在這里我就不展開了,可以查一下瀏覽器的同源策略和跨域的定義。再看后臺(tái)文件文件接收回調(diào)函數(shù)并把要返回的參數(shù)以參數(shù)注入的方式注入到回調(diào)函數(shù)中,再返回給客戶端。 js中的跨域請(qǐng)求應(yīng)該也算是一個(gè)重點(diǎn),具體什么叫跨域,在這里我就不展開了,可以查一下瀏覽器的同源策略和跨域的定義。原來(lái)只知道常用的jsonp和document.domain這兩種方式,這...
摘要:四通過(guò)跨域一個(gè)頁(yè)面嵌入一個(gè)外域的頁(yè)面雖然兩個(gè)窗體之前能獲取彼此的對(duì)象,但是卻拿不到上的屬性和方法,例如一個(gè)頁(yè)面嵌入一個(gè)的我是父窗體的方法嵌入的窗體跟的域名不同,很明顯是跨域的,雖然能獲取到對(duì)象,但是拿不到頁(yè)面的任何方法和屬性。 js跨域是指通過(guò)js在不同域之間進(jìn)行相互通信或者數(shù)據(jù)傳輸,只要協(xié)議,域名,端口號(hào)其中有一個(gè)不同,就是跨域。下面總結(jié)一下我了解到的常用的跨域方法。 一:通過(guò)jso...
閱讀 2439·2021-11-24 11:16
閱讀 2170·2021-09-30 09:47
閱讀 2083·2021-09-10 10:51
閱讀 1373·2019-08-30 14:08
閱讀 3198·2019-08-30 13:47
閱讀 1603·2019-08-30 13:02
閱讀 3283·2019-08-29 12:29
閱讀 3351·2019-08-26 17:05