php main 與 iframe 相互通訊類(js+php同域/跨域)
main 與 iframe 相互通訊類
之前寫過(guò)一篇《iframe與主框架跨域相互訪問(wèn)方法》,介紹了main與iframe相互通訊的原理,不了解原理的可以先看看。
今天把main與iframe相互通訊的方法封裝成類,主要有兩個(gè)文件,
JS:FrameMessage.js 實(shí)現(xiàn)調(diào)用方法的接口,如跨域則創(chuàng)建臨時(shí)iframe,調(diào)用同域執(zhí)行者。
PHP:FrameMessage.class.php 實(shí)現(xiàn)接收到跨域請(qǐng)求時(shí),根據(jù)參數(shù)返回執(zhí)行方法的JS code。
功能如下:
1.支持同域與跨域通訊
2.傳遞的方法參數(shù)支持字符串,JSON,數(shù)組等。
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"]']);
FrameMessage.exec('http://localhost/execA.php', '', 'fMain', ['programmer', '{"first":"PHP","second":"javascript"}', '["EEG","NMG"]']);
因部分瀏覽器不支持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; // 臨時(shí)iframe /* 執(zhí)行方法 executor 執(zhí)行的頁(yè)面,為空則為同域 frame 要調(diào)用的方法的框架名稱,為空則為parent func 要調(diào)用的方法名 args 要調(diào)用的方法的參數(shù),必須為數(shù)組[arg1, arg2, arg3, argn...],方便apply調(diào)用 元素為字符串格式,請(qǐng)不要使用html,考慮注入安全的問(wèn)題會(huì)過(guò)濾 */ 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 : []) : []; // 必須是數(shù)組 if(executor==''){ __fSameDomainExec(); // same domain }else{ __fCrossDomainExec(); // cross domain } } /* 同域執(zhí)行 */ 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); } } /* 跨域執(zhí)行 */ 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(); } } /* 獲取執(zhí)行的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(); } /* 判斷是否數(shù)組 */ 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 根據(jù)參數(shù)調(diào)用方法 * private returnJs 創(chuàng)建返回的javascript * private jsFormat 轉(zhuǎn)義參數(shù) */ class FrameMessage{ // class start /* execute 根據(jù)參數(shù)調(diào)用方法 * @param String $frame 要調(diào)用的方法的框架名稱,為空則為parent * @param String $func 要調(diào)用的方法名 * @param JSONstr $args 要調(diào)用的方法的參數(shù) * @return String */ public static function execute($frame, $func, $args=''){ if(!is_string($frame) || !is_string($func) || !is_string($args)){ return ''; } // frame 與 func 限制只能是字母數(shù)字下劃線 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++){ // 過(guò)濾參數(shù),防止注入 $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.");"); } } /** 創(chuàng)建返回的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; } /** 轉(zhuǎn)義參數(shù) * @param String $str * @return String */ private static function jsFormat($str){ $str = strip_tags(trim($str)); // 過(guò)濾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; ?>
源碼下載地址:點(diǎn)擊查看
相關(guān)文章
自動(dòng)刷新網(wǎng)頁(yè),自動(dòng)刷新當(dāng)前頁(yè)面,JS調(diào)用
自動(dòng)刷新網(wǎng)頁(yè),自動(dòng)刷新當(dāng)前頁(yè)面,JS調(diào)用,需要的朋友可以參考一下2013-06-06JS插入排序簡(jiǎn)單理解與實(shí)現(xiàn)方法分析
這篇文章主要介紹了JS插入排序簡(jiǎn)單理解與實(shí)現(xiàn)方法,結(jié)合實(shí)例形式分析了JavaScript插入排序基本原理、實(shí)現(xiàn)方法及相關(guān)操作注意事項(xiàng),需要的朋友可以參考下2019-11-11javascript 中模板方法單例的實(shí)現(xiàn)方法
這篇文章主要介紹了javascript 中模板方法單例的實(shí)現(xiàn)方法的相關(guān)資料,希望通過(guò)本文能幫助到大家,需要的朋友可以參考下2017-10-10利用JavaScript創(chuàng)建一個(gè)兔年春節(jié)倒數(shù)計(jì)時(shí)器
這篇文章主要介紹了如何利用JavaScript創(chuàng)建一個(gè)兔年春節(jié)倒數(shù)計(jì)時(shí)器,文中的示例代碼講解詳細(xì),對(duì)我們學(xué)習(xí)JavaScript有一定的幫助,需要的可以參考一下2023-01-01Webpack學(xué)習(xí)之動(dòng)態(tài)import原理及源碼分析
這篇文章主要為大家介紹了Webpack學(xué)習(xí)之動(dòng)態(tài)import原理及源碼分析,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2023-04-04JS+CSS制作DIV層可(最小化/拖拽/排序)功能實(shí)現(xiàn)代碼
DIV層最小化和隨意拖拽排序,很多的愛(ài)好者都想實(shí)現(xiàn)這個(gè)功能,小編整理搜集了一下,希望本文的知識(shí)點(diǎn)可以幫助到你2013-02-02javascript中日期函數(shù)new Date()的瀏覽器兼容性問(wèn)題
這篇文章主要介紹了javascript中日期函數(shù)new Date()的瀏覽器兼容性問(wèn)題,需要的朋友可以參考下2015-09-09JS實(shí)現(xiàn)動(dòng)態(tài)無(wú)縫輪播
這篇文章主要為大家詳細(xì)介紹了JS實(shí)現(xiàn)動(dòng)態(tài)無(wú)縫輪播,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2020-01-01