• 技术文章 >后端开发 >php教程

    关于php main 与 iframe 相互通讯类(同域/跨域)的介绍

    jacklovejacklove2018-06-09 14:29:16原创882
    main 与 iframe 相互通讯类

    之前写过一篇《iframe与主框架跨域相互访问方法》,介绍了main与iframe相互通讯的原理,不了解原理的可以先看看。

    今天把main与iframe相互通讯的方法封装成类,主要有两个文件,

    JS:FrameMessage.js 实现调用方法的接口,如跨域则创建临时iframe,调用同域执行者。

    PHP:FrameMessage.class.php 实现接收到跨域请求时,根据参数返回执行方法的JS code。

    功能如下:

    1.支持同域与跨域通讯

    2.传递的方法参数支持字符串,JSON,数组等。

    php入门到就业线上直播课:进入学习


    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.stringifyJSON.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;
    ?>

    本篇文章讲解关于php main 与 iframe 相互通讯类(同域/跨域)的介绍 ,更多相关内容请关注php中文网。

    相关推荐:

    如何使用php 异步调用方法

    如何让php 根据url自动生成缩略图,并处理高并发问题

    关于php 字符串压缩方法之间的比较

    以上就是关于php main 与 iframe 相互通讯类(同域/跨域)的介绍的详细内容,更多请关注php中文网其它相关文章!

    声明:本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn核实处理。

    前端(VUE)零基础到就业课程:点击学习

    清晰的学习路线+老师随时辅导答疑

    自己动手写 PHP MVC 框架:点击学习

    快速了解MVC架构、了解框架底层运行原理

    专题推荐:php iframe
    上一篇:php对象实例化与克隆的使用方法 下一篇:自己动手写 PHP MVC 框架(40节精讲/巨细/新人进阶必看)

    相关文章推荐

    • ❤️‍🔥共22门课程,总价3725元,会员免费学• ❤️‍🔥接口自动化测试不想写代码?• 你知道如何用PHP实现多进程吗• PHP与MySQL连接的方法总结• 求解:phpcms模板怎样转码?该怎么解决• php 之 cookie 跟 session 简单解读(笔记)• php怎的快捷知道某个函数在哪个文件用过
    1/1

    PHP中文网