摘要:四通過跨域一個(gè)頁面嵌入一個(gè)外域的頁面雖然兩個(gè)窗體之前能獲取彼此的對象,但是卻拿不到上的屬性和方法,例如一個(gè)頁面嵌入一個(gè)的我是父窗體的方法嵌入的窗體跟的域名不同,很明顯是跨域的,雖然能獲取到對象,但是拿不到頁面的任何方法和屬性。
js跨域是指通過js在不同域之間進(jìn)行相互通信或者數(shù)據(jù)傳輸,只要協(xié)議,域名,端口號其中有一個(gè)不同,就是跨域。下面總結(jié)一下我了解到的常用的跨域方法。
一:通過jsonp跨域js通過script標(biāo)簽引入一個(gè)外域的資源是不受限制的,jsonp就是利用這個(gè)原理,來實(shí)現(xiàn)跨域的。
callback是前后臺約定的查詢參數(shù),服務(wù)器端返回一個(gè)能執(zhí)行的js文件,這個(gè)js文件是調(diào)用callback對應(yīng)的參數(shù)值即getPrice執(zhí)行,并且返回對應(yīng)的數(shù)據(jù),我們可以在getPrice方法里面來處理返回的數(shù)據(jù),最終返回的結(jié)果如下
getPrice({ "data":{"priceType":"0","unit":"斤"}, "message":"價(jià)格獲取成功!!!", "state":"1" })
jsonp的原理就是這樣,通過Script標(biāo)簽引入一個(gè)js文件,這個(gè)js文件加載成功會執(zhí)行callback對應(yīng)的指定方法,并且把我們需要的數(shù)據(jù)作為參數(shù)傳入,jsonp是需要服務(wù)器端配合的。
$.ajax({ url:"http://wsdetail.b2b.hc360.com/getSupplyPrice", dataType:"jsonp", data:{bcid:"47296567"}, jsonp:"callback", jsonpCallback:"getPrice", success:function(data){ console.log(data); } })
下面是使用jquery的jsonp請求,jsonp只能是get請求,在jquery中jsonpCallback可以省略不寫,jquery會自動生成一個(gè)全局函數(shù)替換callback=對應(yīng)的全局函數(shù),取到數(shù)據(jù)會自動銷毀這個(gè)全局函數(shù);jsonp參數(shù)用來替換“callback=?”中的callback
比如 {jsonp:"callbackOnload"},會生成"?callbackOnload=getPrice"傳給服務(wù)器端;
var xhr = new XMLHttpRequest(); if ("withCredentials" in xhr) { xhr.withCredentials = true; } xhr.open("post", "https://api.growingio.com/v2/9c75e186a1a30142/web/action?stm=1499731328375", true); //true表示異步請求,如果是false則是同步請求, xhr.onreadystatechange = function () { if (xhr.readyState == 4) { if (xhr.status == 200) { var response = xhr.responseText; console.log(response) } } }; xhr.send("data");
XMLHttpRequest最關(guān)鍵部分在服務(wù)器部分 ,其實(shí)無論是否跨域,服務(wù)器都是可以獲取上述請求的。問題的關(guān)鍵在于服務(wù)器的回應(yīng)是否能夠返回到瀏覽器。所以在服務(wù)器發(fā)送回應(yīng)的時(shí)候,需要添加一個(gè)文件頭。這個(gè)文件頭的第一個(gè)參數(shù)是允許跨域,第二個(gè)參數(shù)是接受跨域的服務(wù),
Access-Control-Allow-Origin:http://a.text.com
其實(shí)與不同的XMLHttpRequest還有一個(gè)小小的不同,卻很重要。同域內(nèi)的XMLHttpRequest訪問通常只有一次請求,而跨域的XMLHttpRequest有兩次。
第一次XMLHttpRequest請求,其method是OPTIONS,并非前文定義的POST。這并不是由JS代碼控制的,而是瀏覽器來完成的操作。其作用是判斷該請求是否能夠被服務(wù)器所響應(yīng)。
第二次XMLHttpRequest請求才是真正的POST請求,包含了上傳的文件內(nèi)容。
這里只是對 CORS 做一個(gè)簡單的介紹,如果想更詳細(xì)地了解其原理的話,可以看看下面這篇文章:
阮一峰 跨域資源共享 CORS 詳解
下面介紹三種通過 iframe 跨域與其它頁面通信的方式。
三: 使用html5的postMessage和onmessagepostMessage 是H5新增的api可以使用它來向其它的window對象發(fā)送消息,無論這個(gè)window對象是屬于同源或不同源,目前IE8+、FireFox、Chrome、Opera等瀏覽器都已經(jīng)支持window.postMessage方法。
第一個(gè)參數(shù)是要發(fā)送的數(shù)據(jù),第二個(gè)參數(shù)是接受消息的域,如果不想限定,可以使用通配符"*"
b.text.com域名接受消息的時(shí)候需要通過監(jiān)聽onmessage事件,來獲取傳過來的消息,消息內(nèi)容存儲在事件對象的data屬性中。
window.onmessage=function (e) { e=e||event; alert(e.data); window.parent.postMessage("1234","*") }四:通過document.domain跨域
一個(gè)頁面嵌入一個(gè)外域的iframe頁面,雖然兩個(gè)窗體之前能獲取彼此的window對象,但是卻拿不到window上的屬性和方法,例如一個(gè)http://a.text.com/index.html頁面嵌入一個(gè)http://b.text.com/index.html的iframe
嵌入的窗體跟a.text.com的域名不同,很明顯是跨域的,雖然能獲取到window對象,但是拿不到b頁面的任何方法和屬性。b頁面可以用window.parent拿到父窗體,但是也是同樣不能拿到任何方法和屬性。這個(gè)時(shí)候用document.domain可以解決這種問題
我們在b頁面設(shè)置document.domain,在a頁面也設(shè)置document.domain,document.domain設(shè)置也是有限制的,我們只能把domain設(shè)置成自身或者更高一級的父域。主域必須相同
document.domain="text.com"; function dialog() { alert("ifram里面的方法") } window.parent.parentAlert()
我們在a頁面也設(shè)置一下domain, document.domain="text.com"; 兩個(gè)窗體之間可以正常通信了,這就是通過domain跨域獲取數(shù)據(jù),這種方式只適合兩個(gè)窗體之前,不適合ajax請求;
五:使用 window.name 屬性window對象有一個(gè)name屬性,在一個(gè)窗口生命周期內(nèi),所有載入的頁面共享這個(gè)name屬性,并且都有對這個(gè)name的讀寫權(quán)限。比如有一個(gè)頁面 http://a.text.com/index.html
window.name="我是index頁面設(shè)置的name屬性"; setTimeout(function () { window.location.; },3000)
3秒后載入了b頁面,在b頁面我們獲取window.name,成功的獲取到了index頁面設(shè)置的window.name的值,需要注意的是window.name只能是字符串形式,大小2M左右,下面就來看看具體怎樣通過window.name跨域獲取數(shù)據(jù)
在http://my.b.text.com/index.html頁面嵌入一個(gè)iframe,
var _iframe=document.createElement("iframe"); _iframe.src="http://b.text.com/index.html"; _iframe.style.display="none"; document.body.appendChild(_iframe); _iframe.onload=function () { _iframe.src="about:blank;"; _iframe.onload=function () { alert(_iframe.contentWindow.name); } }
http://b.text.com/index.html頁面設(shè)置window.name
window.name="iframe數(shù)據(jù)"
在http://my.b.text.com/index.html頁面請求http://b.text.com/index.html頁面的數(shù)據(jù),我們可以在頁面建立一個(gè)iframe,src指向請求的地址,利用iframe的跨域能力
在請求的頁面設(shè)置window.name的值。 但是由于 my.b.text.com 頁面和該頁面 iframe 的 src 如果不同源的話,則無法操作 iframe 里的任何東西,所以就取不到 iframe 的 name 值,所以我們需要在 b.text.com 加載完后重新?lián)Q個(gè) src 去指向一個(gè)同源的 html 文件,或者設(shè)置成 "about:blank;"
改變iframe的src指向后,這個(gè)時(shí)候在監(jiān)聽iframe的onload屬性,就可以獲取到iframe的window.name屬性了;
文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請注明本文地址:http://specialneedsforspecialkids.com/yun/87152.html
摘要:二跨域解決方案原理利用標(biāo)簽沒有跨域限制的漏洞,網(wǎng)頁可以得到從其他來源動態(tài)產(chǎn)生的數(shù)據(jù)。使用反向代理實(shí)現(xiàn)跨域,是最簡單的跨域方式。 前言 前后端數(shù)據(jù)交互經(jīng)常會碰到請求跨域,什么是跨域,以及有哪幾種跨域方式,這是本文要探討的內(nèi)容。 本文完整的源代碼請猛戳github博客,紙上得來終覺淺,建議動手敲敲代碼 一、什么是跨域? 1.什么是同源策略及其限制內(nèi)容? 同源策略是一種約定,它是瀏覽器最核心...
摘要:二跨域解決方案原理利用標(biāo)簽沒有跨域限制的漏洞,網(wǎng)頁可以得到從其他來源動態(tài)產(chǎn)生的數(shù)據(jù)。使用反向代理實(shí)現(xiàn)跨域,是最簡單的跨域方式。 前言 前后端數(shù)據(jù)交互經(jīng)常會碰到請求跨域,什么是跨域,以及有哪幾種跨域方式,這是本文要探討的內(nèi)容。 本文完整的源代碼請猛戳github博客,紙上得來終覺淺,建議動手敲敲代碼 一、什么是跨域? 1.什么是同源策略及其限制內(nèi)容? 同源策略是一種約定,它是瀏覽器最核心...
摘要:中的跨域請求應(yīng)該也算是一個(gè)重點(diǎn),具體什么叫跨域,在這里我就不展開了,可以查一下瀏覽器的同源策略和跨域的定義。再看后臺文件文件接收回調(diào)函數(shù)并把要返回的參數(shù)以參數(shù)注入的方式注入到回調(diào)函數(shù)中,再返回給客戶端。 js中的跨域請求應(yīng)該也算是一個(gè)重點(diǎn),具體什么叫跨域,在這里我就不展開了,可以查一下瀏覽器的同源策略和跨域的定義。原來只知道常用的jsonp和document.domain這兩種方式,這...
摘要:之前我們講了一下四種跨域的方式四種跨域方式詳解。這四種方式是使用純來進(jìn)行跨域的。今天就介紹兩種有涉及到服務(wù)器的跨域技術(shù)。 之前我們講了一下四種 JavaScript 跨域的方式 - 「JavaScript」四種跨域方式詳解。這四種方式是使用純 JavaScript 來進(jìn)行跨域的。 今天就介紹兩種有涉及到服務(wù)器的跨域技術(shù)。 一、反向代理服務(wù)器 基礎(chǔ)思想很簡單,將你的服務(wù)器配置成 需要跨域...
閱讀 924·2021-10-27 14:14
閱讀 1749·2021-10-11 10:59
閱讀 1321·2019-08-30 13:13
閱讀 3157·2019-08-29 15:17
閱讀 2756·2019-08-29 13:48
閱讀 494·2019-08-26 13:36
閱讀 2087·2019-08-26 13:25
閱讀 862·2019-08-26 12:24