最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

postMessage及webSocket跨域方案詳解

 更新時(shí)間:2022年10月11日 10:58:56   作者:mouche  
這篇文章主要為大家介紹了postMessage及webSocket跨域方案詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪

一、postMessage

我們?cè)谏弦黄?a href="http://m.fzitv.net/article/264734.htm" rel="external nofollow" target="_blank">小白也能搞懂的JSONP和CORS跨域方案已經(jīng)說(shuō)過(guò)兩種跨域方案了,這一篇就再繼續(xù)講講postMessagewebsocket這兩種方案,它們也能算得上是跨域方案??

?是什么

  • window.postMessage() 方法提供了一種受控機(jī)制來(lái)規(guī)避此限制,只要正確的使用,這種方法就很安全
  • 聽(tīng)聽(tīng)MDN的解釋?zhuān)阂粋€(gè)窗口可以獲得對(duì)另一個(gè)窗口的引用,然后在窗口上調(diào)用 targetWindow.postMessage() 方法分發(fā)一個(gè) MessageEvent 消息。接收消息的窗口可以根據(jù)需要自由處理此事件

?語(yǔ)法

targetWindow.postMessage(message, targetOrigin, [transfer]);
  • targetWindow: 其他窗口的一個(gè)引用,比如 iframecontentWindow 屬性、執(zhí)行window.open返回的窗口對(duì)象、或者是命名過(guò)或數(shù)值索引的window.frames (en-US)
  • message: 將要發(fā)送到其他 window 的數(shù)據(jù)。它將會(huì)被結(jié)構(gòu)化克隆算法 (en-US)序列化。這意味著你可以不受什么限制的將數(shù)據(jù)對(duì)象安全的傳送給目標(biāo)窗口而無(wú)需自己序列化
  • targetOrigin: 通過(guò)窗口的 origin 屬性來(lái)指定哪些窗口能接收到消息事件,其值可以是字符串*(表示無(wú)限制)或者一個(gè) URI。在發(fā)送消息的時(shí)候,如果目標(biāo)窗口的協(xié)議、主機(jī)地址或端口這三者的任意一項(xiàng)不匹配它提供的值,那么消息就不會(huì)被發(fā)送;只有三者完全匹配,消息才會(huì)被發(fā)送。這個(gè)機(jī)制用來(lái)控制消息可以發(fā)送到哪些窗口
  • transfer 可選: 是一串和 message 同時(shí)傳遞的 Transferable 對(duì)象。這些對(duì)象的所有權(quán)將被轉(zhuǎn)移給消息的接收方,而發(fā)送一方將不再保有所有權(quán)。

通過(guò)以上敘述我們能夠了解到它的作用就是可以安全地給目標(biāo)窗口發(fā)送自定義的信息

?怎么用

有信息的發(fā)送,自然也要有信息的接收,我們可以采用addEventLister,監(jiān)聽(tīng)message事件: 該事件接收到消息時(shí)觸發(fā)

  • 我們先在同一個(gè)窗口對(duì)其進(jìn)行測(cè)試(在Origin值為http://127.0.0.1:5500/的頁(yè)面打開(kāi))
const data = {
  name : '某車(chē)',
  like:  '前端'
}
//傳入的message為data,targetOrigin為http://127.0.0.1:5500/
window.postMessage(data, 'http://127.0.0.1:5500/');
window.addEventListener('message',(event)=>{
//監(jiān)聽(tīng)該回調(diào)事件并打印
  console.log(event);
})
  • 我們看一下打印臺(tái),可以看到里面的data正是我們傳入的數(shù)據(jù),origin是發(fā)送消息的源,source為發(fā)送消息的窗口引用(后面這兩個(gè),用于我們回發(fā)消息,實(shí)現(xiàn)消息互通)

?如何跨域

上述我們提到了其他窗口的引用可以是iframecontentWindow屬性,也可以是window.open的返回值那么我們就都來(lái)試試看

iframe + postMessage

  • 這里是使用3300端口父頁(yè)面向內(nèi)嵌子頁(yè)面3301端口發(fā)送消息
//a.html
 <!-- 使用iframe,src指向3301端口 -->
<iframe src="http://127.0.0.1:3301/b.html" id="frame" onload="load()"></iframe>
<script>
const data = {
  name : '某車(chē)',
  like:  '前端'
}
const load = function(){
  //負(fù)責(zé)發(fā)布消息
  let frame = document.getElementById('frame'); 
  const targetWindow = frame.contentWindow;//得到目標(biāo)窗口的引用
  targetWindow.postMessage(data, 'http://127.0.0.1:3301'); //發(fā)送新消息
  //也監(jiān)聽(tīng)信息
  window.onmessage = function(event) {
    console.log(event.data)
  }
}
</script>
  • 這里記得在onload事件里面去觸發(fā),否則會(huì)報(bào)如下錯(cuò)誤

  • 3301端口監(jiān)聽(tīng)message事件,然后通過(guò)event.source得到3300端口頁(yè)面的引用,event.origin獲取3300端口的源,然后可以回發(fā)消息
    //b.html
    window.addEventListener('message',(event)=>{
      console.log(event.data);
      event.source.postMessage('我可以回發(fā)消息給你', event.origin);
    })

3300端口頁(yè)面的打印 (圖片端口號(hào)打錯(cuò)了,懶得修改了..)

window.open()+postMessage

先認(rèn)知一下window.open()語(yǔ)法

window.open(url, [name], [configuration])
  • url:為要新打開(kāi)頁(yè)面的url
  • name:為新打開(kāi)窗口的名字,可以通過(guò)此名字獲取該窗口對(duì)象
  • configuration:為新打開(kāi)窗口的一些配置項(xiàng),比如是否有菜單欄、滾動(dòng)條、長(zhǎng)高等等信息

還是上面的思路,我們讓3300端口3301端口發(fā)送信息

   //a.html
  <button class="openWindow">打開(kāi)窗口</button>
  <script>
    const btn = document.querySelector('.openWindow');
    const data = {
      name : '某車(chē)',
      like:  '前端'
    }
    //點(diǎn)擊之后,執(zhí)行window.open()
    btn.addEventListener('click', ()=>{
     const targetWindow =  window.open('http://127.0.0.1:3301/b.html', '3001端口'); //拿到目標(biāo)窗口的引用
     setTimeout(()=>{
      targetWindow.postMessage(data, 'http://127.0.0.1:3301/'); //發(fā)送數(shù)據(jù)
     },1000)
    })
    //同時(shí)監(jiān)聽(tīng)message事件
    window.addEventListener('message',(event)=>{
      console.log(event.data);
    })
  </script>
  • 3301端口監(jiān)聽(tīng)message事件,并且回發(fā)信息
    //b.html
    window.addEventListener('message',(event)=>{
      console.log(event.data);
      event.source.postMessage('我可以回發(fā)消息給你', event.origin);
    })
  • 看一下控制臺(tái)結(jié)果

3301端口打印如下

3300端口打印如下

?兼容性

還是在IE有兼容問(wèn)題

小結(jié):postMessage()方法允許來(lái)自不同源的腳本進(jìn)行有限的通信,只要能獲取到源和窗口對(duì)象就可以實(shí)現(xiàn)跨域消息傳遞

二、webSocket

  • webSocket是一種在單個(gè)TCP連接上進(jìn)行全雙工通信的協(xié)議,它實(shí)現(xiàn)了瀏覽器與服務(wù)器全雙工通信,能更好的節(jié)省服務(wù)器資源和帶寬并達(dá)到實(shí)時(shí)通訊的目的
  • WebSocketHTTP都是應(yīng)用層協(xié)議,都基于 TCP 協(xié)議
  • 只需要一次握手(使用HTTP協(xié)議)客戶端和服務(wù)端就可以建立持久性的鏈接,進(jìn)行雙向數(shù)據(jù)傳輸

?出現(xiàn)的原因

  • 需要實(shí)現(xiàn)“聊天室”,“消息推送”,“實(shí)時(shí)動(dòng)態(tài)”等功能
  • 曾經(jīng)的方案:
    • 短輪詢;每隔一段時(shí)間就詢問(wèn)一次服務(wù)器是否有新的消息,缺點(diǎn)就是有一定的延遲,浪費(fèi)資源
    • 長(zhǎng)輪詢:客戶端發(fā)送請(qǐng)求后如果數(shù)據(jù)沒(méi)有更新的話服務(wù)器就先將其掛起,有新消息則傳回,等傳回后又重新發(fā)起請(qǐng)求等待數(shù)據(jù)更新,缺點(diǎn)就是服務(wù)器需要保持大量的連接

?連接流程

  • 客戶端先用Upgrade:Websocket請(qǐng)求頭的HTTP請(qǐng)求,向服務(wù)器發(fā)起握手請(qǐng)求
Connnection:Upgrade  //表示要升級(jí)協(xié)議
Upgrade: websocket //表示要升級(jí)為websocket協(xié)議
Sec-webSocket-Version:13 //版本
  • 握手成功后,即升級(jí)協(xié)議,兩端就可以相互傳遞消息了

?兼容性

為什么說(shuō)它是解決跨域的方案:因?yàn)樗旧砭筒皇芡床呗缘南拗?,客戶端可以和任意服?wù)器之間進(jìn)行通信

跨域小結(jié)

  • JSONP因?yàn)閮H支持get請(qǐng)求,淘汰無(wú)人問(wèn)津是遲早的事情
  • CORS支持所有類(lèi)型的HTTP請(qǐng)求,是跨域HTTP請(qǐng)求的根本解決方案,但是我們上一篇也提了,還是有IE兼容問(wèn)題
  • postMessage方法允許來(lái)自不同源的腳本進(jìn)行有限的通信,只要能獲取到源和窗口對(duì)象就可以實(shí)現(xiàn)跨域消息傳遞
  • websocket本身不受同源策略的限制,可以在不同源間進(jìn)行通信
  • 最后還有nginx反向代理,它可以說(shuō)基本沒(méi)啥毛???不過(guò)我不怎么了解它就不介紹啦??

以上就是postMessage及webSocket跨域方案詳解的詳細(xì)內(nèi)容,更多關(guān)于postMessage webSocket跨域的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

  • 淺談typescript中keyof與typeof操作符用法

    淺談typescript中keyof與typeof操作符用法

    本文主要介紹了typescript中keyof與typeof操作符用法,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2022-06-06
  • Javascript必知必會(huì)(四)js類(lèi)型轉(zhuǎn)換

    Javascript必知必會(huì)(四)js類(lèi)型轉(zhuǎn)換

    這篇文章主要介紹了Javascript必知必會(huì)(四)js類(lèi)型轉(zhuǎn)換 的相關(guān)資料,非常不錯(cuò)具有參考借鑒價(jià)值,需要的朋友可以參考下
    2016-06-06
  • 使用JavaScript實(shí)現(xiàn)彈出層效果的簡(jiǎn)單實(shí)例

    使用JavaScript實(shí)現(xiàn)彈出層效果的簡(jiǎn)單實(shí)例

    下面小編就為大家?guī)?lái)一篇使用JavaScript實(shí)現(xiàn)彈出層效果的簡(jiǎn)單實(shí)例。小編覺(jué)得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧
    2016-05-05
  • javascript下對(duì)于事件、事件流、事件觸發(fā)的順序隨便說(shuō)說(shuō)

    javascript下對(duì)于事件、事件流、事件觸發(fā)的順序隨便說(shuō)說(shuō)

    向同一個(gè)標(biāo)簽 動(dòng)態(tài)的添加事件是 執(zhí)行的順序在ie和其他非ie內(nèi)核的瀏覽器有所不同 ie是“先進(jìn)先出 ” 就是最先添加的最先執(zhí)行,其他非ie內(nèi)核的瀏覽器是 “先進(jìn)后出”,就是 最后添加的事件 先執(zhí)行。
    2010-07-07
  • 一文詳解javascript語(yǔ)言中的類(lèi)(class)

    一文詳解javascript語(yǔ)言中的類(lèi)(class)

    class類(lèi)是一種抽象的體現(xiàn),用來(lái)表示具有相同特性的一類(lèi)事物,是面向?qū)ο缶幊滩豢扇鄙俚墓ぞ?下面這篇文章主要介紹了javascript語(yǔ)言中類(lèi)class的相關(guān)資料,文中通過(guò)代碼介紹的非常詳細(xì),需要的朋友可以參考下
    2025-04-04
  • zTree插件之多選下拉菜單實(shí)例代碼

    zTree插件之多選下拉菜單實(shí)例代碼

    zTree插件之多選下拉菜單實(shí)例代碼。需要的朋友可以過(guò)來(lái)參考下,希望對(duì)大家有所幫助
    2013-11-11
  • 對(duì)Web開(kāi)發(fā)中前端框架與前端類(lèi)庫(kù)的一些思考

    對(duì)Web開(kāi)發(fā)中前端框架與前端類(lèi)庫(kù)的一些思考

    這篇文章主要介紹了對(duì)Web開(kāi)發(fā)中前端框架與前端類(lèi)庫(kù)的一些思考,本文講解了前端框架的理解誤區(qū)、前端框架與前端類(lèi)庫(kù)的區(qū)別、前端MVC框架思想等內(nèi)容,需要的朋友可以參考下
    2015-03-03
  • js函數(shù)獲取html中className所在的內(nèi)容并去除標(biāo)簽

    js函數(shù)獲取html中className所在的內(nèi)容并去除標(biāo)簽

    本文為大家介紹下如何使用js函數(shù)獲取html中className所在的內(nèi)容,具體實(shí)現(xiàn)思路如下,喜歡的朋友可以參考下
    2013-09-09
  • js實(shí)現(xiàn)的常用的左側(cè)導(dǎo)航效果

    js實(shí)現(xiàn)的常用的左側(cè)導(dǎo)航效果

    使用js簡(jiǎn)單實(shí)現(xiàn)下常用的左側(cè)導(dǎo)航效果為提高導(dǎo)航性能而生,各位朋友可以參考應(yīng)用,希望對(duì)大家有所幫助
    2013-10-10
  • javascript里模擬sleep(兩種實(shí)現(xiàn)方式)

    javascript里模擬sleep(兩種實(shí)現(xiàn)方式)

    有幾種方式,但都不完美 其一:不斷循環(huán),直到達(dá)到指定時(shí)間、其二:用xhr同步請(qǐng)求后臺(tái)程序,比如傳2000過(guò)去,后臺(tái)就sleep 2秒后再返回,這種方式也有缺點(diǎn),當(dāng)N多客戶端都請(qǐng)求后臺(tái)時(shí),一直保持連接http開(kāi)銷(xiāo)很大,感興趣的朋友可以了解下啊
    2013-01-01

最新評(píng)論

福海县| 安国市| 科技| 普兰县| 色达县| 海兴县| 孟州市| 商城县| 萨迦县| 承德县| 横山县| 镶黄旗| 华亭县| 洛阳市| 建湖县| 丹巴县| 磐石市| 天柱县| 信丰县| 定西市| 秦安县| 日土县| 宣恩县| 南岸区| 曲麻莱县| 运城市| 灵武市| 阜新市| 昭觉县| 寿宁县| 白朗县| 连山| 青川县| 潮州市| 三河市| 连南| 清原| 湛江市| 轮台县| 元阳县| 翁牛特旗|