您好,登錄后才能下訂單哦!
main 與 iframe 相互通訊類
之前寫過一篇《iframe與主框架跨域相互訪問方法》,介紹了main與iframe相互通訊的原理,不了解原理的可以先看看。
今天把main與iframe相互通訊的方法封裝成類,主要有兩個文件,
JS:FrameMessage.js 實現調用方法的接口,如跨域則創建臨時iframe,調用同域執行者。
PHP:FrameMessage.class.php 實現接收到跨域請求時,根據參數返回執行方法的JS code。
功能如下:
1.支持同域與跨域通訊
2.傳遞的方法參數支持字符串,JSON,數組等。
因部分瀏覽器不支持JSON.stringify 與JSON.parse 方法(如IE6/7),為了兼容,需要包含json2.js,下載地址:
https://github.com/douglascrockford/JSON-js
FrameMessage.js
/** 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
<?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); return $str; } } // class end ?>
A.html
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> <html> <head> <meta http-equiv="content-type" content="text/html; charset=utf-8"> <title> main window </title> <script type="text/javascript" src="json2.js"></script> <script type="text/javascript" src="FrameMessage.js"></script> <script type="text/javascript"> // main js function function fMain(profession, skill, company){ var skill_p = JSON.parse(skill); var company_p = JSON.parse(company); var msg = "main function execute success\n\n"; msg += "profession:" + profession + "\n"; msg += "first skill:" + skill_p.first + "\n"; msg += "second skill:" + skill_p.second + "\n"; msg += "company1:" + company_p[0] + "\n"; msg += "company2:" + company_p[1] + "\n"; alert(msg); } // exec iframe function function exec_iframe(){ // same domain //FrameMessage.exec('', 'myframe', 'fIframe', ['fdipzone', '{"gender":"male","age":"29"}', '["http://blog.csdn.net/fdipzone", "http://weibo.com/fdipzone"]']); // cross domain 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"]']); } </script> </head> <body> <p>A.html main</p> <p><input type="button" value="exec iframe function" onclick="exec_iframe()"></p> <!-- same domain --> <!--<iframe src="B.html" name="myframe" width="500" height="100"></iframe>--> <!-- cross domain --> <iframe src="http://127.0.0.1/B.html" name="myframe" width="500" height="100"></iframe> </body> </html>
B.html
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> <html> <head> <meta http-equiv="content-type" content="text/html; charset=utf-8"> <title> iframe window </title> <script type="text/javascript" src="json2.js"></script> <script type="text/javascript" src="FrameMessage.js"></script> <script type="text/javascript"> // iframe js function function fIframe(name, obj, arr){ var obj_p = JSON.parse(obj); var arr_p = JSON.parse(arr); var msg = "iframe function execute success\n\n"; msg += "name:" + name + "\n"; msg += "gender:" + obj_p.gender + "\n"; msg += "age:" + obj_p.age + "\n"; msg += "blog:" + arr_p[0] + "\n"; msg += "weibo:" + arr_p[1] + "\n"; alert(msg); } // exec main function function exec_main(){ // same domain //FrameMessage.exec('', '', 'fMain', ['programmer', '{"first":"PHP","second":"javascript"}', '["EEG","NMG"]']); // cross domain FrameMessage.exec('http://localhost/execA.php', '', 'fMain', ['programmer', '{"first":"PHP","second":"javascript"}', '["EEG","NMG"]']); } </script> </head> <body> <p>B.html iframe</p> <p><input type="button" value="exec main function" onclick="exec_main()"></p> </body> </html>
execA.php 與 execB.php
<?php require 'FrameMessage.class.php'; $frame = isset($_GET['frame'])? $_GET['frame'] : ''; $func = isset($_GET['func'])? $_GET['func'] : ''; $args = isset($_GET['args'])? $_GET['args'] : ''; $result = FrameMessage::execute($frame, $func, $args); echo $result; ?>
源碼下載地址:點擊查看
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。