跨域訪問的解決方案(HTML5的方法:postMessage)
關於跨域訪問,使用JSONP的方法,我前面已經demo過了,具體見http://supercharles888.blog.51cto.com/609344/856886,HTML5提供了一個非常強大的API,叫postMessage,它其實就是以前iframe的進化版本,使用起來極其方便,這裡舉個實驗例子:
我們依舊按照與上文相同的設定,假定我們有2個Domain
Domain1: http://localhost:8080 它上面有個應用叫HTMLDomain1,並且有個頁面叫sender.html。
Domain2:http://localhost:8180 它上面有個應用叫HTMLDomain2,並且有個頁面叫receiver.html。
我現在的需求是,假定Domain1上我們有個json資料,我們想讓Domain2應用中的javascript要可以操作這個json 資料(注意,這裡已經是跨域了,因為Domain2上的js操作了Domain1上的資料),應該怎麼辦呢?
解決方案就是用HTML5的postMessage方法
Domain2的程式碼:
首先,我們在Domain2上建立一個HTML頁面,這個頁面沒什麼內容,就一行文字會來標識它是Domain 2,它下方將來會被js用來填充從Domain1弄過來的資料。
- <!DOCTYPE html>
- <html>
- <head>
- <meta charset=“UTF-8”>
- <title>Domain2上的接收者頁面receiver.html</title>
- <script type=“text/javascript” src=“js/receiveInfo.js”></script>
- </head>
- <body onload=“receiveInfoFromAnotherDomain();”>
- <p>這個頁面是HTML5跨域訪問的Domain2上的頁面receiver.html,它會處理來自Domain1上sender.html傳送的頁面</p>
- </body>
- </html>
Domain2頁面載入時候,它會呼叫receiveInfoFromAnotherDomain()函式,這個函式首先定義了一個事件監聽函式,它只接受來自Domain1(http://localhost:8080)的事件,否則就忽略掉,然後它從這個事件中分離出資訊負載,也就是json 資料,然後顯示在頁面底部:
- //這個函式用於處理從Domain1上的sender傳送過來的資訊,然後將他們列印出來
- function receiveInfoFromAnotherDomain(){
- console.log(“entering method receiveInfoFromAnotherDomain()”);
- //首先讓window新增一個事件監聽函式,表明它可以監聽視窗物件的message事件
- //它受到事件時,會先判斷是否來自指定的Domain(不是所有Domain丟過來的事件它都處理的)
- window.addEventListener(“message”,function(ev){
- console.log(“the receiver callback func has been invoked”);
- //如果不是來自指定Domain的,則忽略
- if(ev.origin !=“http://localhost:8080”){
- console.log(“the event doesn`t come from Domain1!”);
- return;
- }
- //現在可以處理資料了
- //控制檯列印出接收到的json資料,因為我們把json字串傳送了過來
- console.log(ev.data);
- //將json字串轉為json物件,然後從中分離出原始資訊
- var personInfoJSON = JSON.parse(ev.data);
- var name = personInfoJSON.name;
- var title = personInfoJSON.title;
- var info = personInfoJSON.info;
- //構造資訊文字並且顯示在頁面的底部
- var personInfoString=“從域為: “+ev.origin+“那裡傳來的資料.”+“<br>”;
- personInfoString+=“姓名是: “+name+“<br>”;
- personInfoString+=“頭銜為: “+title+“<br>”;
- personInfoString+=“資訊為: “+info+“<br>”;
- document.body.innerHTML=personInfoString;
- }
- );
- }
然後將Domain2 (http://localhost:8180)啟動起來,不出意外,它將是:
Domain1的程式碼:
現在,我們來構建Domain1:
為了讓Domain1能夠和Domain2通過事件互動,我們用了iframe,把Domain2的頁面receiver.html以<iframe>形式鑲嵌在Domain1的sender.html頁面中。
- <!DOCTYPE html>
- <html>
- <head>
- <meta charset=“UTF-8”>
- <title>Domain1上的傳送者頁面sender.html</title>
- <script type=“text/javascript” src=“js/sendInfo.js”></script>
- </head>
- <body>
- <p>這個頁面是HTML5跨域訪問的Domain1上的頁面sender.html,它將傳送一些資訊到Domain2上的receiver.html</p>
- <input type=“button” value=“點選則傳送事件到Domain2” onclick=“sendInfoToAnotherDomain();”/>
- <!– 這個iframe包含了在另外一個domain->Domain2(http://localhost:8180)的接收者頁面receiver.html –>
- <iframe width=“1200” src=“http://localhost:8180/HTML5Domain2/receiver.html”></iframe>
- </body>
- </html>
同時我們在頁面上建立一個button,當點選它就會傳送json資料給Domain2.
所以js函式就負責以json字串形式傳送json資料,然後讓iframe中的Domain2頁面傳送資訊,注意這裡接受者的視窗在iframe中,所以我們用iframe.postMessage,第一個引數是我們的資訊載體,這裡是json字串,第二個引數是目標Domain,也就是Domain2
- //假定這個Domain(Domain1)要把一些json資訊傳送到另一個域(Domain2)的某個頁面
- function sendInfoToAnotherDomain(){
- console.log(“entering method: sendInfoToAnotherDomain()”);
- //首先構造一個物件,內含有我們想要傳送到Domain2的資訊,然後把它轉為json字串
- var personInfo= new Object;
- personInfo.name=`charles`;
- personInfo.title=`technical lead`;
- personInfo.info=“talent man”;
- var str=JSON.stringify(personInfo);
- console.log(“The information to be send: “+str);
- //我們把這個json字串傳送到Domain2
- //因為這個Domain2上的目標頁面被嵌在了主頁面上作為iframe,所以我們取得這個iframe然後讓他來傳送資訊
- //資訊的內容是我們的包含個人資訊內容的json字串
- var iframe=window.frames[0];
- iframe.postMessage(str,`http://localhost:8180`);
- console.log(“json string has been sent to domain2 successfully”);
- }
這樣一來,我們就定義了傳送者(Domain1)和接收者(Domain2),傳送者由於嵌了<iframe>所以頁面看上去如下圖:
當點選”點選則傳送事件到Domain2″ 按鈕後,json資料資訊被髮送到了Domain2,因為Domain2的事件監聽程式註冊了監聽來自Domain1的事件,所以它可以把事件中攜帶的json字串解析成原始資訊,然後構造文字顯示在Domain2的receiver.html的下方,如圖:(可以比照sendInfoToAnotherDomain(),可以發現資訊是完全匹配的)
相關文章
- 分享跨域訪問的解決方案與基礎分析跨域
- 解決JS跨域訪問的問題JS跨域
- HTML5 window.postMessage 與跨域HTML跨域
- Angular應用解決跨域訪問的問題Angular跨域
- 跨域問題,解決方案 – CORS方案跨域CORS
- 解決Django本地介面不能跨域訪問的問題Django跨域
- 跨域問題及解決方案跨域
- SpringBoot跨域問題解決方案Spring Boot跨域
- spring boot解決跨域訪問配置Spring Boot跨域
- 前端跨域的解決方案前端跨域
- 解決ajax跨域問題的多種方法跨域
- 前端跨域問題及其解決方案前端跨域
- Flutter Web 跨域問題解決方案FlutterWeb跨域
- nginx /Java 解決跨域問題方案NginxJava跨域
- 跨域的原因以及解決方案跨域
- Nginx解決前端訪問資源跨域問題Nginx前端跨域
- vue-cli下跨域 問題的解決方法Vue跨域
- 跨域訪問是什麼!怎麼解決?跨域
- Vue中跨域問題解決方案1Vue跨域
- 跨域的九種解決方法跨域
- 常見的跨域解決方案(全)跨域
- iris 跨域解決方案跨域
- Nuxt使用axios跨域問題解決方法UXiOS跨域
- 簡單的瞭解跨域以及解決方案跨域
- Laravel6.X 跨域問題解決方案Laravel跨域
- 解決跨域問題跨域
- SignalR跨域解決方案全面SignalR跨域
- js跨域解決方案(一)JS跨域
- Web 學習之跨域問題及解決方案Web跨域
- localStorage 跨域訪問跨域
- 搞懂:前端跨域問題JS解決跨域問題VUE代理解決跨域問題原理前端跨域JSVue
- Vue 前端跨域的解決方案(心得記錄)Vue前端跨域
- 一種方便的跨域開發解決方案跨域
- 使用Nginx來解決跨域的問題Nginx跨域
- 跨域多方位解決方案跨域
- 跨域解決方案(總結篇)跨域
- WebSocket跨域問題解決Web跨域
- Java解決跨域問題Java跨域
- Flask解決跨域問題Flask跨域