日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 前端技术 > javascript >内容正文

javascript

javascript中实现跨域的方式总结

發(fā)布時(shí)間:2025/6/15 javascript 41 豆豆
生活随笔 收集整理的這篇文章主要介紹了 javascript中实现跨域的方式总结 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

js中的跨域請(qǐng)求應(yīng)該也算是一個(gè)重點(diǎn),具體什么叫跨域,在這里我就不展開了,可以查一下瀏覽器的同源策略和跨域的定義。原來只知道常用的jsonp和document.domain這兩種方式,這幾天學(xué)習(xí)了一下其他幾種跨域請(qǐng)求的方式,正好一起做個(gè)總結(jié)。

第一種方式:jsonp請(qǐng)求

jsonp請(qǐng)求應(yīng)該是大家最為熟悉的一種(至少是我知道的第一種跨域請(qǐng)求方式)。jsonp的原理是利用<script>標(biāo)簽的跨域特性,可以不受限制地從其他域中加載資源,類似的標(biāo)簽還有<img>.利用<script>標(biāo)簽的這個(gè)特性可以從服務(wù)器中返回需要的跨域數(shù)據(jù)。下面用代碼的小例子加以分析:
例子中html文件和后臺(tái)php(這里我以php后臺(tái)為例,后臺(tái)我自己會(huì)的是php)文件位于不同域中!

先看html文件:

文件底部的<script>標(biāo)簽的src鏈接到后臺(tái)service.php文件,并傳入?yún)?shù)callback,這里的關(guān)鍵是把回調(diào)函數(shù)作為參數(shù)傳給后臺(tái)。

再看后臺(tái)php文件:

文件接收回調(diào)函數(shù)并把要返回的參數(shù)以參數(shù)注入的方式注入到回調(diào)函數(shù)中,再返回給客戶端。

這樣的話瀏覽器解析script標(biāo)簽,并執(zhí)行返回的js文檔,此時(shí)服務(wù)器返回的數(shù)據(jù)作為參數(shù),傳到頁面中定義好的 jsonpBack 函數(shù)里.(動(dòng)態(tài)執(zhí)行回調(diào)函數(shù)),就拿到了我們需要的跨域數(shù)據(jù)。

這里補(bǔ)充一點(diǎn)就是jquery對(duì)jsonp有著很好的支持,jquery中$.getJSON方法將jsonp的調(diào)用方式進(jìn)行了封裝,用起來十分方便,使用的方式如下即可:

<script> $.getJSON("后臺(tái)文件地址?參數(shù)=**",function(jsondata){ //在這里就可以操作從后臺(tái)拿到的jsondata數(shù)據(jù) }) </script>

第二種方式:document.domain

這種方式用在主域名相同子域名不同的跨域訪問中,舉個(gè)例子:http://a.frame.com和http://b.frame.com 他們的主域名都是frame.com 這兩個(gè)域名中的文件可以用這種方式進(jìn)行訪問,通過在兩個(gè)域中具體的文件中設(shè)置document.domain="frame.com"就可達(dá)到跨域訪問的目的。

實(shí)際應(yīng)用中常常用在iframe中窗口之間的訪問,根據(jù)瀏覽器的同源策略,瀏覽器中不同域的框架之間是不能進(jìn)行js的交互操作的,所以一個(gè)窗口是不能拿到另一個(gè)窗口中的contentWindow對(duì)象的屬性和方法的(注意是能拿到contentWindow對(duì)象的,只是屬性和方法都不可用)。為了能拿到數(shù)據(jù),只要在兩個(gè)iframe中分別寫入document.domain="主域名",這樣設(shè)置之后,就能拿到contentWindow對(duì)象的屬性和方法了。代碼就這么簡單的一行,我就不寫小例子了。

第三種方式:window.name

window的name屬性有個(gè)特征:在一個(gè)窗口(window)的生命周期內(nèi),窗口載入的所有的頁面都是共享一個(gè)window.name的,每個(gè)頁面對(duì)window.name都有讀寫的權(quán)限,window.name是持久存在一個(gè)窗口載入過的所有頁面中的,并不會(huì)因新頁面的載入而進(jìn)行重置。

這是什么意思呢?通俗來講,就是比如我在a.html這個(gè)頁面中設(shè)置了window.name="a";然后讓window重新加載b.html頁面,然后在b.html頁面中輸出window.name會(huì)發(fā)現(xiàn)window.name=“a”。所以就算a.html和b.html這兩個(gè)頁面不是在同一個(gè)域中的,也可以在b頁面中拿到a頁面設(shè)置的window.name的值,跨域的核心思路就是這個(gè)原理。

實(shí)際應(yīng)用中也是常常用在兩個(gè)iframe之間(需要結(jié)合iframe的特性來用),先上一張從別人那邊借鑒過來的原理圖,我再按照自己的理解進(jìn)行分析:

圖中有三個(gè)頁面,getDomainData.html是獲取數(shù)據(jù)的頁面,null.html是一個(gè)和getDomainData.html同域的空頁面,它的作用是作為一個(gè)中轉(zhuǎn)站,進(jìn)行數(shù)據(jù)的過渡。data.html是要獲取數(shù)據(jù)的所在頁面,這里有著我們要的數(shù)據(jù),它和getDomainData.html處于不同域中,所以取數(shù)據(jù)是跨域訪問。具體的過程是這樣的:在getDomainData.html中建立一個(gè)子頁面iframe,把這個(gè)iframe的src指向b.com/data.html,這樣當(dāng)這個(gè)iframe加載完成后就可以訪問到data.html中的window.name的數(shù)據(jù),之后再將iframe的src改為a.com/null.html,跳回getDomainData.html的同一個(gè)域,這樣根據(jù)同源策略,getDomainData.html就可以訪問到null.html中取得的data.html的數(shù)據(jù)了。獲取數(shù)據(jù)以后最好銷毀這個(gè)iframe,釋放掉內(nèi)存,也保證了安全。下面附上代碼小例子:

getDomainData.html:

<script type="text/javascript">var flag=0;var data;var iframe=document.createElement("iframe");//創(chuàng)建一個(gè)中轉(zhuǎn)站iframedocument.appendChild(iframe);getData=function(){//iframe加載完成后調(diào)用的處理函數(shù)if(flag==1){data=iframe.contentWindow.name;//讀取b.html中的window.name}else{flag=1;iframe.src="http://a.com/null.html";//跳回getDomainData.html的同一個(gè)域}};iframe.src="http://b.com/data.html";//設(shè)置src到要獲得數(shù)據(jù)的域中的對(duì)應(yīng)頁面if (iframe.attachEvent) {//兼容IE,監(jiān)聽iframe加載完成iframe.attachEvent('onload', getData);} else {iframe.addEventListener('load',getData);}</script>

data.html:

<script> window.name="被獲取數(shù)據(jù)"//簡單的一行代碼 </script>

最后的iframe銷毀:

<script>iframe.contentWindow.document.write("");//情況iframe中的內(nèi)容iframe.contentWindow.close();//避免iframe的內(nèi)存泄漏document.body.removeChild(iframe);//移除iframe節(jié)點(diǎn) </script>

第四種方式:window.postMessage

window.postMessages是html5中實(shí)現(xiàn)跨域訪問的一種新方式,可以使用它來向其它的window對(duì)象發(fā)送消息,無論這個(gè)window對(duì)象是屬于同源或不同源。
該方式的使用還是十分簡單的,給要發(fā)送數(shù)據(jù)的頁面中的window對(duì)象調(diào)用一個(gè)postMessage(message,targetOrigin)方法即可,該方法的第一個(gè)參數(shù)message為要發(fā)送的消息,類型只能為字符串;第二個(gè)參數(shù)targetOrigin用來限定接收消息的那個(gè)window對(duì)象所在的域,如果不想限定域,直接使用通配符 * 。再讓接收數(shù)據(jù)頁面的window對(duì)象監(jiān)聽自身的message事件來獲取傳過來的消息,消息內(nèi)容儲(chǔ)存在該事件對(duì)象的data屬性中。簡單的小例子如下:

test.html(發(fā)送頁面):

<script> <iframe name="receive" id="iframe" src="test2.html" scrolling="no"></iframe> <script type="text/javascript">window.onload=function(){var iframWindow = document.getElementById("iframe").contentWindow;iframWindow.postMessage("A secret", "*");//發(fā)送消息} </script>

test2.html(接收頁面)

<script>window.addEventListener("message",function(e){alert(e.data);//接收到的消息}) </script>

測試結(jié)果如下

關(guān)于這個(gè)用法困擾了我好久,困擾1:因?yàn)樽詈髲棾龅南⑹窃趖est.html,而不是在test2.html中,我不確定是因?yàn)閠est.html包含了test2.html,所以瀏覽器渲染才彈出的alert,還是test2.html接收到消息的反饋。后來查閱了權(quán)威的文檔,才有了進(jìn)一步的理解,應(yīng)該是test2.html收到消息,以iframe在test.html中渲染加載出的。
困擾2:postMessage的調(diào)用對(duì)象是目標(biāo)窗口還是發(fā)送窗口,是否能以window形式調(diào)用?
查閱文檔后得出結(jié)論:*postMessage的調(diào)用對(duì)象,是其他窗口的一個(gè)引用,即目標(biāo)窗口,不是要發(fā)送的窗口,(這里比較出乎意料) 而且postMessage想要通信必須使得一個(gè)窗口以iframe的形式存在于另一個(gè)窗口,或者一個(gè)窗口是從另一個(gè)窗口通過window.open()或者超鏈接的形式打開的(同樣可以用window.opener獲取源窗口);換句話說,你要交換數(shù)據(jù),必須能獲取目標(biāo)窗口(target window)的引用,不然兩個(gè)窗口之間毫無聯(lián)系,想通信也無能為力,所以不能直接以主頁面window的形式調(diào)用。

具體的權(quán)威解釋請(qǐng)看這個(gè)鏈接: window.postMessage

第五種方式:CORS

CORS(Corss-Origin-Resource Sharing,跨源資源共享),是一種網(wǎng)絡(luò)瀏覽器的技術(shù)規(guī)范,它為Web服務(wù)器定義了一種方式,允許網(wǎng)頁從不同的域訪問其資源,而這種訪問是被同源策略所禁止的。CORS系統(tǒng)定義了一種瀏覽器和服務(wù)器交互的方式來確定是否允許跨域請(qǐng)求。 它是一個(gè)妥協(xié),有更大的靈活性,但比起簡單地允許所有這些的要求來說更加安全。
CORS背后的基本思想,就是使用自定義的HTTP頭部讓瀏覽器與服務(wù)器進(jìn)行溝通,從而決定請(qǐng)求或響應(yīng)是應(yīng)該成功還是應(yīng)該失敗。

CORS的使用還是十分簡便的,比如一個(gè)簡單的GET或者POST請(qǐng)求,在發(fā)送的時(shí)候給它附加一個(gè)額外的origin頭部,其中包含請(qǐng)求頁面的源信息(協(xié)議、域名和端口),以便服務(wù)器根據(jù)這個(gè)頭部信息來決定是否給以響應(yīng)。下面是javascript高級(jí)程序設(shè)計(jì)書上的一個(gè)小例子:

Origin:http://www.nczonline.net

如果服務(wù)器認(rèn)為這個(gè)請(qǐng)求可以接受,就在Access-Control-Allow-Origin頭部中回發(fā)相同的源消息(如果是公共資源,可以回發(fā)“ * ”)。例如:

Access-Control-Allow-Origin:http://www.nczonline.net

這樣設(shè)置之后,服務(wù)器與瀏覽器就可以進(jìn)行跨域信息的交換了。具體的在不同瀏覽器上的支持和使用,我就不展開了,js高級(jí)程序設(shè)計(jì)書上提到了很多,網(wǎng)上查一下也有很多。

第六種方式:Web Sockets

Web Sockets是一種新瀏覽器API,能在一個(gè)單獨(dú)的持久連接上提供全雙工、雙向通信,使用ws(代替http://)或wss(代替https://)協(xié)議,可用于任意的客戶端和服務(wù)器程序。
web sockets原理:在JS創(chuàng)建了web socket之后,會(huì)有一個(gè)HTTP請(qǐng)求發(fā)送到瀏覽器以發(fā)起連接。取得服務(wù)器響應(yīng)后,建立的連接會(huì)使用HTTP升級(jí)從HTTP協(xié)議交換為web sockt協(xié)議。
使用的小例子:

// 創(chuàng)建一個(gè)Socket實(shí)例 var socket = new WebSocket('ws://www.example.com/server.php'); // 打開Socket socket.onopen = function(event) { // 發(fā)送消息socket.send('a secret'); // 監(jiān)聽消息的接收socket.onmessage = function(event) { var data=event.data;//處理data...}; // 監(jiān)聽socket的關(guān)閉socket.onclose = function(event) { console.log('socket has closed',event); }; // 關(guān)閉Socket//socket.close() };

同樣附上權(quán)威文檔供參考:Web Workers API

總結(jié)

除此之外還有一些跨域訪問的方式:比如Comet、圖像Ping、SSE等,感興趣的可以直接查找這些內(nèi)容。在這些跨域訪問方式上,各有各的適用訪問和相應(yīng)的限制,需要結(jié)合實(shí)際來適用。我在這里有個(gè)疑問:我自己運(yùn)用的比較多的就是jsonp這種方式,那么在實(shí)際開發(fā)中,比較推崇的跨域訪問方式是哪種呢?還有就是html5的postMessage是不是可以取代window.name(同樣都需要一個(gè)iframe作為中間媒介)這類訪問方式,這個(gè)新API方式是不是在實(shí)際中很有效呢?希望有經(jīng)驗(yàn)的大牛可以解答,不勝感激。

《新程序員》:云原生和全面數(shù)字化實(shí)踐50位技術(shù)專家共同創(chuàng)作,文字、視頻、音頻交互閱讀

總結(jié)

以上是生活随笔為你收集整理的javascript中实现跨域的方式总结的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。

主站蜘蛛池模板: 超碰2023 | 蜜臀av一区二区三区有限公司 | 国产精品xxx在线观看 | www.在线观看麻豆 | 精品久久久99 | 无码少妇一级AV片在线观看 | 国产做爰xxxⅹ久久久精华液 | 亚洲欧美日韩一区二区三区四区 | 在线观看av的网站 | 夜夜躁狠狠躁日日躁av | 91精品视频在线看 | 永久黄网站 | 97自拍偷拍视频 | av首页在线观看 | 欧美精品一区二 | www.夜夜夜| 少妇色| 丁香婷婷综合激情 | 免费观看久久久 | av中出在线 | 色欲av伊人久久大香线蕉影院 | 无码人妻丰满熟妇区五十路 | 天天射视频 | 美女露隐私网站 | 亚洲综合免费观看高清完整版在线 | 五月天啪啪 | 欧美熟妇精品一区二区蜜桃视频 | 成人在线观看一区二区 | 日韩激情视频在线观看 | 亚洲性xxx| 精品一区久久久 | 亚洲一区二区三区中文字幕 | 日韩免费一区二区三区 | 欧美久久久影院 | 色婷婷久久综合中文久久蜜桃av | gogo亚洲国模私拍人体 | fc2ppv在线播放 | 阿的白色内裤hd中文 | 五月天激情婷婷 | 99久久久精品免费观看国产 | 色综合久久久久久 | 麻豆精品一区 | 红色假期黑色婚礼2 | 国产精品av网站 | 日本成人在线视频网站 | 内射无码专区久久亚洲 | 午夜天堂视频 | 色网在线免费观看 | 亚洲精品乱码久久久久久麻豆不卡 | 国产老头老太作爱视频 | 亚洲欧美在线视频 | 国产精品中文字幕在线 | 成人精品视频一区二区三区尤物 | 欧美精品在线观看一区二区 | 国产黄色大片视频 | 在线步兵区 | 日美毛片 | 91在线欧美 | 女人被男人躁得好爽免费视频 | 天天躁狠狠躁 | 亚洲性久久| 日本天堂网 | 美女扒开尿口给男人捅 | 农村黄色片 | 我的大叔| 天堂成人国产精品一区 | 国产精品无码av在线有声小说 | 免费大片av | chinese麻豆新拍video| 你懂得在线视频 | 毛片毛片毛片毛片毛片毛片毛片毛片毛片 | 亚洲成人视屏 | 久久久福利视频 | 成年人福利网站 | 亚洲怡春院 | 东北毛片| 国产激情视频一区二区 | 国产激情片 | 99热官网 | 婷婷丁香激情 | 日本高清不卡在线 | 亚洲熟妇无码乱子av电影 | 国产精品自拍网 | 搞中出 | 日本bbwbbw| 日韩欧美一本 | 999视频在线播放 | 高h喷水荡肉少妇爽多p视频 | 日韩国产欧美视频 | 亚洲午夜精品久久久久久浪潮 | 亚洲一级黄色片 | 亚洲精品xxx | 日韩女优一区 | h片在线观看视频 | 男生坤坤放进女生坤坤里 | 在线成人一区二区 | 含羞草一区二区三区 | 成在人线av| 亚洲精品18|