Einführung in die gegenseitige Kommunikation zwischen PHP Main und Iframe

巴扎黑
Freigeben: 2023-03-16 08:08:01
Original
1214 Leute haben es durchsucht

这篇文章主要介绍了php main 与 iframe 相互通讯类(js+php同域/跨域),需要的朋友可以参考下

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,下载地址:

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;

}());
Nach dem Login kopieren

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=&#39;&#39;){

    if(!is_string($frame) || !is_string($func) || !is_string($args)){
      return &#39;&#39;;
    }

    // frame 与 func 限制只能是字母数字下划线
    if(($frame!=&#39;&#39; && !preg_match(&#39;/^[A-Za-z0-9_]+$/&#39;,$frame)) || !preg_match(&#39;/^[A-Za-z0-9_]+$/&#39;,$func)){
      return &#39;&#39;;
    }

    $params_str = &#39;&#39;;

    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 = "&#39;".implode("&#39;,&#39;", $params)."&#39;";
      }
    }

    if($frame==&#39;&#39;){ // 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 = &#39;<script type="text/javascript">&#39;."\r\n";
    $ret .= $str."\r\n";
    $ret .= &#39;</script>&#39;;

    return $ret;
  }


  /** 转义参数
  * @param String $str
  * @return String
  */
  private static function jsFormat($str){

    $str = strip_tags(trim($str)); // 过滤html
    $str = str_replace(&#39;\\s\\s&#39;, &#39;\\s&#39;, $str);
    $str = str_replace(chr(10), &#39;&#39;, $str);
    $str = str_replace(chr(13), &#39;&#39;, $str);
    $str = str_replace(&#39; &#39;, &#39;&#39;, $str);
    $str = str_replace(&#39;\\&#39;, &#39;\\\\&#39;, $str);
    $str = str_replace(&#39;"&#39;, &#39;\\"&#39;, $str);
    $str = str_replace(&#39;\\\&#39;&#39;, &#39;\\\\\&#39;&#39;, $str);
    $str = str_replace("&#39;", "\&#39;", $str);

    return $str;
  }

} // class end

?>
Nach dem Login kopieren

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(&#39;&#39;, &#39;myframe&#39;, &#39;fIframe&#39;, [&#39;fdipzone&#39;, &#39;{"gender":"male","age":"29"}&#39;, &#39;["http://blog.csdn.net/fdipzone", "http://weibo.com/fdipzone"]&#39;]);

	// cross domain
	FrameMessage.exec(&#39;http://127.0.0.1/execB.php&#39;, &#39;myframe&#39;, &#39;fIframe&#39;, [&#39;fdipzone&#39;, &#39;{"gender":"male","age":"29"}&#39;, &#39;["http://blog.csdn.net/fdipzone", "http://weibo.com/fdipzone"]&#39;]);
 }
 </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>
Nach dem Login kopieren

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(&#39;&#39;, &#39;&#39;, &#39;fMain&#39;, [&#39;programmer&#39;, &#39;{"first":"PHP","second":"javascript"}&#39;, &#39;["EEG","NMG"]&#39;]);

	// cross domain
	FrameMessage.exec(&#39;http://localhost/execA.php&#39;, &#39;&#39;, &#39;fMain&#39;, [&#39;programmer&#39;, &#39;{"first":"PHP","second":"javascript"}&#39;, &#39;["EEG","NMG"]&#39;]); 
 }
 </script>

 </head>

 <body>
 <p>B.html iframe</p>
 <p><input type="button" value="exec main function" onclick="exec_main()"></p>
 </body>
</html>
Nach dem Login kopieren

execA.php 与 execB.php


<?php
require &#39;FrameMessage.class.php&#39;;

$frame = isset($_GET[&#39;frame&#39;])? $_GET[&#39;frame&#39;] : &#39;&#39;;
$func = isset($_GET[&#39;func&#39;])? $_GET[&#39;func&#39;] : &#39;&#39;;
$args = isset($_GET[&#39;args&#39;])? $_GET[&#39;args&#39;] : &#39;&#39;;

$result = FrameMessage::execute($frame, $func, $args);

echo $result;
?>
Nach dem Login kopieren

Das obige ist der detaillierte Inhalt vonEinführung in die gegenseitige Kommunikation zwischen PHP Main und Iframe. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Verwandte Etiketten:
Quelle:php.cn
Erklärung dieser Website
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn
Beliebte Tutorials
Mehr>
Neueste Downloads
Mehr>
Web-Effekte
Quellcode der Website
Website-Materialien
Frontend-Vorlage