php main 與 iframe 相互連訊類(同域/跨域)

來源:互聯網
上載者:User
main 與 iframe 相互連訊類

之前寫過一篇《iframe與主架構跨域相互存取方法》,介紹了main與iframe相互連訊的原理,不瞭解原理的可以先看看。


今天把main與iframe相互連訊的方法封裝成類,主要有兩個檔案,

JS:FrameMessage.js 實現調用方法的介面,如跨域則建立臨時iframe,調用同域執行者。

PHP:FrameMessage.class.php 實現接收到跨域請求時,根據參數返回執行方法的JS code。


功能如下:

1.支援同域與跨域通訊

2.傳遞的方法參數支援字串,JSON,數組等。



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,下載地址:http://www.php.cn/


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 domainFrameMessage.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 domainFrameMessage.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



<?phprequire '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;?>


以上就是php main 與 iframe 相互連訊類(同域/跨域) 的內容,更多相關內容請關注topic.alibabacloud.com(www.php.cn)!

  • 聯繫我們

    該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

    如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

    A Free Trial That Lets You Build Big!

    Start building with 50+ products and up to 12 months usage for Elastic Compute Service

    • Sales Support

      1 on 1 presale consultation

    • After-Sales Support

      24/7 Technical Support 6 Free Tickets per Quarter Faster Response

    • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.