1. 程式人生 > >JavaScript使ifram跨域相互訪問及與PHP通訊的例項

JavaScript使ifram跨域相互訪問及與PHP通訊的例項

iframe 與主框架相互訪問方法

1.同域相互訪問

假設A.html 與 b.html domain都是localhost (同域)
A.html中iframe 嵌入 B.html,name=myframe
A.html有js function fMain()
B.html有js function fIframe()
需要實現 A.html 呼叫 B.html 的 fIframe(),B.html 呼叫 A.html 的 fMain()

A.html

?
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" > <html> <head> <meta http-equiv="content-type" content="text/html; charset=utf-8"> <title> main window </title> <script type="text/javascript"> // main js function function fMain(){ alert('main function execute success'
); } // exec iframe function function exec_iframe(){ window.myframe.fIframe(); } </script> </head> <body> <p>A.html main</p> <p><input type="button" value="exec iframe function" onclick="exec_iframe()"></p> <iframe src="B.html" name="myframe"
width="500" height="100"></iframe> </body> </html>

B.html

?
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" > <html> <head> <meta http-equiv="content-type" content="text/html; charset=utf-8"> <title> iframe window </title> <script type="text/javascript"> // iframe js function function fIframe(){ alert('iframe function execute success'); } // exec main function function exec_main(){ parent.fMain(); } </script> </head> <body> <p>B.html iframe</p> <p><input type="button" value="exec main function" onclick="exec_main()"></p> </body> </html>

點選A.html 的 exec iframe function button,執行成功,彈出iframe function execute success。如下圖

201633165209664.jpg (537×208)

點選B.html 的 exec main function button,執行成功,彈出 main function execute success。如下圖

201633165228804.jpg (536×208)

2.跨域互相訪問

假設 A.html domain是 localhost, B.html domain 是 127.0.0.1 (跨域)
這裡使用 localhost 與 127.0.0.1 只是方便測試,localhost 與 127.0.0.1已經不同一個域,因此執行效果是一樣的。
實際使用時換成 www.domaina.com 與 www.domainb.com 即可。
A.html中iframe 嵌入 B.html,name=myframe
A.html有js function fMain()
B.html有js function fIframe()
需要實現 A.html 呼叫 B.html 的 fIframe(),B.html 呼叫 A.html 的 fMain() (跨域呼叫)

如果使用上面同域的方法,瀏覽器判斷A.html 與 B.html 不同域,會有錯誤提示。
Uncaught SecurityError: Blocked a frame with origin "http://localhost" from accessing a frame with origin "http://127.0.0.1". Protocols, domains, and ports must match.

實現原理:
因為瀏覽器為了安全,禁止了不同域訪問。因此只要呼叫與執行的雙方是同域則可以相互訪問。

首先,A.html 如何呼叫B.html的 fIframe方法
1.在A.html 建立一個 iframe
2.iframe的頁面放在 B.html 同域下,命名為execB.html
3.execB.html 裡有呼叫B.html fIframe方法的js呼叫

?
1 2 3 <script type="text/javascript"> parent.window.myframe.fIframe(); // execute parent myframe fIframe function </script>

這樣A.html 就能通過 execB.html 呼叫 B.html 的 fIframe 方法了。

同理,B.html 需要呼叫A.html fMain方法,需要在B.html 嵌入與A.html 同域的 execA.html
execA.html 裡有呼叫 A.html fMain 方法的js 呼叫

?
1 2 3 <script type="text/javascript"> parent.parent.fMain(); // execute main function </script>

這樣就能實現 A.html 與 B.html 跨域相互呼叫。

A.html

?
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" > <html> <head> <meta http-equiv="content-type" content="text/html; charset=utf-8"> <title> main window </title> <script type="text/javascript"> // main js function function fMain(){ alert('main function execute success'); } // exec iframe function function exec_iframe(){ if(typeof(exec_obj)=='undefined'){ exec_obj = document.createElement('iframe'); exec_obj.name = 'tmp_frame'; exec_obj.style.display = 'none'; document.body.appendChild(exec_obj); }else{ } } </script> </head> <body> <p>A.html main</p> <p><input type="button" value="exec iframe function" onclick="exec_iframe()"></p> <iframe src= name="myframe" width="500" height="100"></iframe> </body> </html>

B.html

?
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" > <html> <head> <meta http-equiv="content-type" content="text/html; charset=utf-8"> <title> iframe window </title> <script type="text/javascript"> // iframe js function function fIframe(){ alert('iframe function execute success'); } // exec main function function exec_main(){ if(typeof(exec_obj)=='undefined'){ exec_obj = document.createElement('iframe'); exec_obj.name = 'tmp_frame'; exec_obj.style.display = 'none'; document.body.appendChild(exec_obj); }else{ } } </script> </head> <body> <p>B.html iframe</p> <p><input type="button" value="exec main function" onclick="exec_main()"></p> </body> </html>

execA.html

?
1 2 3 4 5 6 7 8 9 10 11 12 13 <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" > <html> <head> <meta http-equiv="content-type" content="text/html; charset=utf-8"> <title> exec main function </title> </head> <body> <script type="text/javascript"> parent.parent.fMain(); // execute main function </script> </body> </html>

execB.html

?
1 2 3 4 5 6 7 8 9 10 11 12 13 <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" > <html> <head> <meta http-equiv="content-type" content="text/html; charset=utf-8"> <title> exec iframe function </title> </head> <body> <script type="text/javascript"> parent.window.myframe.fIframe(); // execute parent myframe fIframe function </script> </body> </html>

執行如下圖:

201633165339112.jpg (529×214)


php main 與 iframe 相互通訊類(同域/跨域)
把main與iframe相互通訊的方法封裝成類,主要有兩個檔案,
JS:FrameMessage.js 實現呼叫方法的介面,如跨域則建立臨時iframe,呼叫同域執行者。
PHP:FrameMessage.class.php 實現接收到跨域請求時,根據引數返回執行方法的JS code。

功能如下:
1.支援同域與跨域通訊
2.傳遞的方法引數支援字串,JSON,陣列等。

201633165429252.jpg (549×249)

複製程式碼 程式碼如下: FrameMessage.exec('http://127.0.0.1/execB.php', 'myframe', 'fIframe', ['fdipzone', '{"gender":"male","age":"29"}', '["http://blog.csdn.net/fdipzone", "http://weibo.com/fdipzone"]']); 

201633170000506.jpg (527×242)

複製程式碼 程式碼如下: FrameMessage.exec('http://localhost/execA.php', '', 'fMain', ['programmer', '{"first":"PHP","second":"javascript"}', '["EEG","NMG"]']);

FrameMessage.js

?
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 /** Main 與 Iframe 相互通訊類 支援同域與跨域通訊 * Date: 2013-12-29 * Author: fdipzone * Ver: 1.0 */ var FrameMessage = (function(){ this.oFrameMessageExec = null; // 臨時iframe /* 執行方法 executor 執行的頁面,為空則為同域 frame 要呼叫的方法的框架名稱,為空則為parent func  要呼叫的方法名 args  要呼叫的方法的引數,必須為陣列[arg1, arg2, arg3, argn...],方便apply呼叫 元素為字串格式,請不要使用html,考慮注入安全的問題會過濾 */ this.exec = function(executor, frame, func, args){ this.executor = typeof(executor)!='undefined'? executor : ''; this.frame = typeof(frame)!='undefined'? frame : ''; this.func = typeof(func)!='undefined'? func : ''; this.args = typeof(args)!='undefined'? (__fIsArray(args)? args : []) : []; // 必須是陣列 if(executor==''){ __fSameDomainExec(); // same domain }else{ __fCrossDomainExec(); // cross domain } } /* 同域執行 */ function __fSameDomainExec(){ if(this.frame==''){ // parent parent.window[this.func].apply(this, this.args); }else{ window.frames[this.frame][this.func].apply(this, this.args); } } /* 跨域執行 */ function __fCrossDomainExec(){ if(this.oFrameMessageExec == null){ this.oFrameMessageExec = document.createElement('iframe'); this.oFrameMessageExec.name = 'FrameMessage_tmp_frame'; this.oFrameMessageExec.src = __fGetSrc(); this.oFrameMessageExec.style.display = 'none'; document.body.appendChild(this.oFrameMessageExec); }else{ this.oFrameMessageExec.src = __fGetSrc(); } } /* 獲取執行的url */ function __fGetSrc(){ return this.executor + (this.executor.indexOf('?')==-1? '?' : '&') + 'frame=' + this.frame + '&func=' + this.func + '&args=' + JSON.stringify(this.args) + '&framemessage_rand=' + Math.random(); } /* 判斷是否陣列 */ function __fIsArray(obj){ return Object.prototype.toString.call(obj) === '[object Array]'; } return this; }());

FrameMessage.class.php

?
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 <?php /** Frame Message class main 與 iframe 相互通訊類 * Date: 2013-12-29 * Author: fdipzone * Ver: 1.0 * * Func: * public execute 根據引數呼叫方法 * private returnJs 建立返回的javascript * private jsFormat 轉義引數 */ class FrameMessage{ // class start /* execute 根據引數呼叫方法 * @param String $frame 要呼叫的方法的框架名稱,為空則為parent * @param String $func 要呼叫的方法名 * @param JSONstr $args 要呼叫的方法的引數 * @return String */ public static function execute($frame, $func, $args=''){ if(!is_string($frame) || !is_string($func) || !is_string($args)){ return ''; } // frame 與 func 限制只能是字母數字下劃線 if(($frame!='' && !preg_match('/^[A-Za-z0-9_]+$/',$frame)) || !preg_match('/^[A-Za-z0-9_]+$/',$func)){ return ''; } $params_str = ''; if($args){ $params = json_decode($args, true); if(is_array($params)){ for($i=0,$len=count($params); $i<$len; $i++){ // 過濾引數,防止注入 $params[$i] = self::jsFormat($params[$i]); } $params_str = "'".implode("','", $params)."'"; } } if($frame==''){ // parent return self::returnJs("parent.parent.".$func."(".$params_str.");"); }else{ return self::returnJs("parent.window.".$frame.".".$func."(".$params_str.");"); } } /** 建立返回的javascript * @param String $str * @return String */ private static function returnJs($str){ $ret = '<script type="text/javascript">'."\r\n"; $ret .= $str."\r\n"; $ret .= '</script>'; return $ret; } /** 轉義引數 * @param String $str * @return String */ private static function jsFormat($str){ $str = strip_tags(trim($str)); // 過濾html $str = str_replace('\\s\\s', '\\s', $str); $str = str_replace(chr(10), '', $str); $str = str_replace(chr(13), '', $str); $str = str_replace(' ', '', $str); $str = str_replace('\\', '\\\\', $str); $str = str_replace('"', '\\"', $str); $str = str_replace('\\\'', '\\\\\'', $str); $str = str_replace("'", "\'", $str);

相關推薦

JavaScript使ifram相互問及PHP通訊例項

iframe 與主框架相互訪問方法 1.同域相互訪問 假設A.html 與 b.html domain都是localhost (同域) A.html中iframe 嵌入 B.html,name=myframe A.html有js function fMain() B.htm

JavaScript 和Ajax問題

pre class log message callback sun javascrip llb back json格式: { "message":"獲取成功", "state":"1", "result":{"name":"工作組1","id":

javascript中實現的方式總結

第一種方式:jsonp請求;jsonp的原理是利用&lt;script&gt;標籤的跨域特性,可以不受限制地從其他域中載入資源,類似的標籤還有&lt;img&gt;. 第二種方式:document.domain;這種方式用在主域名相同子域

iframe主框架相互訪問方法

iframe 與主框架相互訪問方法 1.同域相互訪問 假設A.html 與 b.html domain都是localhost (同域) A.html中iframe 嵌入 B.html,name=myframe A.html有js funct

Ajax請求 同源策略Jsonp

就是 pen 針對 api 自己的 發送請求 cdn esp 自己 同源策略(Same origin policy)是一種約定,它是瀏覽器最核心也最基本的安全功能,如果缺少了同源策略,則瀏覽器的正常功能可能都會受到影響。可以說Web是構建在同源策略基礎之上的,瀏覽器只是

Web:簡述""的概念造成原因

Web:簡述"跨域"的概念與造成原因 一、什麼是跨域?    當協議、子域名、主域名、埠號中任意一個不相同時,都算作不同域。不同域之間相互請求資源,就算作"跨域"。 注意:     &n

jsonp請求,vue-resource + php前後端分裂做webapp

PHP做響應jsonp的操作。 我做跨域用到了vue-resource ,這個百度一下就能下載: 下面是HTML頁面ajax: 加上 v-model=" " 之後;js方法裡會檢查到裡面的 value

drf框架之問題的解決緩存問題

content com 超時 pda cti header event port ade 什麽是跨域問題呢: 1. 跨域問題: CORS 跨域資源共享: 有簡單請求 和非簡單請求 簡單請求: 只要符合如下兩條,就是簡單請求,否

cors之簡單請求預檢請求(傳送自定義請求頭)

引子 前後端分離這個問題,對cors的應用不斷增多,暴露出的問題也接踵而至。 正所謂慮一千次,不如去做一次。 猶豫一萬次,不如

django做服務端 window.name javascript實現原理及實例

字符串 tex 並且 ble blog char src 兩個 splay 項目地址:https://github.com/blff122620/jsLibary/tree/master/crossDomainDemo 原理如下:window.name 傳輸技術,原本是 T

WebSocket 解決javascript問題一劑良藥

群發 通過 網上服務 script nss 項目 經驗 子頁面 時間 近日做項目中遇到javascript跨域問題,父頁面和子頁面要通信,並且父子頁面跨域,怎麽辦? 大家結合以前經驗,想到了Websocket,websocket客戶端編程比較簡單,服務端我們用

javascript

想要 如果 .cn https 直接 fun 獲取json 為什麽 cross 什麽是跨域? 為什麽瀏覽器要限制跨域? 以上的問題在相關博客介紹的更為詳盡,不做描述。 帶來了哪些問題? 我再8097端口想要訪問8090的靜態資源(字體或者css什麽的)是被

javascript訪問探索之旅

是否 list 好的 掌握 HR edi 性能 擁有 developer 需求: ??????? 近期工作負責一個互聯網應用A(我公司應用)與還有一個互聯網應用B進

的根本原因:JavaScript 的同源策略

內嵌 index.php vid cor hat opera rust 跨站 高度 摘自:https://blog.csdn.net/liubo2012/article/details/43148705 同源策略限制了一個源(origin)中加載文本或腳本與來自其它源(or

[整理]JavaScript解決方法大全

跨域的定義:Javascript出於安全性考慮,同源策略機制對跨域訪問做了限制。域僅僅是通過“URL的首部”字串進行識別,“URL的首部”指window.location.protocol +window.location.host,也可以理解為“Domains, protocols and por

楊老師課堂之Jquery的篩選,事件,效果,Ajax,javascript)

1 篩選[掌握]  篩選與之前“選擇器”雷同,篩選提供函式 1.1 過濾 eq(index|-index),獲取第N個元素 •index:一個整數,指示元素基於0的位置,這個元素的位置是從0算起。 •-index:一個整數,指示元素的位置,從集合中的最後一個元素開

Javascript 使用postMessage對iframe傳值或通訊

實現目標:兩個網站頁面實現跨域相互通訊 當前例子依賴於 jQuery 3.0 父頁面程式碼:www.a.com/a.html <iframe id="myIframe" src="http://www.b.com/b.html"></iframe> <script&g

javascript 請求

post 方法一 服務端 header('Access-Control-Allow-Origin:*'); $data = json_encode(array("id" => "1", "name" => "tom")); echo $data; 前端 $

javascript:什麼是,如何(轉載自小鬍子哥)

---恢復內容開始---   無數次看到:Origin null is not allowed by Access-Control-Allow-Origin , 網路沒有讓你絕望,但是或許會讓你蛋疼,因為你找了半天沒看到一個比較實用的解決方案,亦或者水平不夠,別人寫的東西累贅沒看懂,抑或是。。。

JavaScript問題

三種方法實現js跨域訪問 javascript跨域訪問是web開發者經常遇到的問題,什麼是跨域,一個域上載入的指令碼獲取或操作另一個域上的文件屬性,下面將列出三種實現javascript跨域方法: 1.基於iframe實現跨域 基於iframe實現的跨域要求兩個域具有aa.xx.co