JavaScript实现的双向跨域插件分享


Posted in Javascript onJanuary 31, 2015

由于浏览器(同源策略)限制,JavaScript 跨域的问题,一直是一个颇为棘手的问题。HTML5 提供了跨文档消息传输的功能,在网页文档之间互相接收与发送信息。使用这个功能,不仅同源(域 + 端口号)的 Web 网页之间可以互相通信,还可以在两个不同域名之间实现跨域通信。

跨文档消息传输Cross Document Messaging提供了postMessage方法在不同网页文档之间互相传递数据,支持实时消息传递。现在很多浏览器都将支持这个功能,比如Google Chrome 2.0+、Internet Explorer 8.0+、Firefox 3.0+、Opera 9.6+、Safari 4.0+等

那么,IE6、IE7等不支持 HTML5的浏览器怎么办?

可以使用window.name方法,因为window.name的修改不涉及跨域问题,虽然使用起来不是特别理想,但效果还可以接受。
但是,我们总不能每次涉及到跨域都去写一遍window.postMessage、window.addEventListener、window.name等等这些内容吧。

为此,我把这整个跨域过程抽象出来,封装成一个JavaScript 插件,解决双向跨域问题,实现不同网页文档之间的实时通信,可以在两个不同域名之间实现跨域通信。

demo下载地址:http://xiazai.3water.com/201501/other/jcrossdomain_v2.rar,版本v2

javascript跨域插件jcrossdomain.js

(function (win){

  /** 

   * 没有开花的树 

   * 2013/12/07 17:12 

   */ 

  var _jcd = {

    isInited : false,

    elmt : false,

    hash : '',

    delims : ',',

    rand : function(){

      return (new Date).getTime()

    },

    msg : function(){

      alert('Warning: You must call init function at first');

    },

    init : function(callback, elmt){

      if(_jcd.isInited == true)

        return;

      _jcd.isInited = true;

      _jcd.elmt = elmt;

      if(win.postMessage){

        //浏览器支持 HTML5 postMessage 方法

        if(win.addEventListener){

          //支持火狐、谷歌等浏览器

          win.addEventListener("message", function(ev){

            callback.call(win, ev.data);

          },false);

        }else if(win.attachEvent){

          //支持IE浏览器

          win.attachEvent("onmessage", function(ev){

            callback.call(win, ev.data);

          });

        }

        _jcd.msg = function(data){

          _jcd.elmt.postMessage(data, '*');

        }

      }else{

        //浏览器不支持 HTML5 postMessage 方法,如IE6、7

        setInterval(function(){

          if (win.name !== _jcd.hash) {

            _jcd.hash = win.name;

            callback.call(win, _jcd.hash.split(_jcd.delims)[1]);

          }

        }, 50);

        _jcd.msg = function(data){

          _jcd.elmt.name = _jcd.rand() + _jcd.delims + data;

        }

      }

    }

  };
  var jcd = {
    initParent : function(callback, iframeId){

      _jcd.init(callback, document.getElementById(iframeId).contentWindow);

    },
    initChild : function(callback){

      _jcd.init(callback, win.parent);

    },
    sendMessage : function(data){

      _jcd.msg(data);

    }
  };

  win.jCrossDomain = jcd;

})(window);

父网页中调用方法:

//自定义回调函数

var cb = function(msg){

  alert("get msg:" + msg);

};
//初始化,载入回调函数和 iframe 的id

jCrossDomain.initParent(cb, 'iframeA');
//发消息

jCrossDomain.sendMessage('hello, child');

子网页中调用方法:

//自定义回调函数

var cb = function(msg){

  alert("get msg:" + msg);

};
//初始化,载入回调函数

jCrossDomain.initChild(cb);
//发消息

jCrossDomain.sendMessage('hello, parent');

模拟测试小提示:
为了实现不同域之间的通信,可以在操作系统的 hosts 文件添加两个域名,进行模拟。

hosts 文件中添加两个不同的域名
127.0.0.1  parent.com
127.0.0.1  child.com

程序猿的进化过程:

JavaScript实现的双向跨域插件分享

Javascript 相关文章推荐
js实现键盘上下左右键选择文字并显示在文本框的方法
May 07 Javascript
利用HTML5的画布Canvas实现刮刮卡效果
Sep 06 Javascript
jquery仅用6行代码实现滑动门效果
Sep 07 Javascript
JS中setTimeout的巧妙用法前端函数节流
Mar 24 Javascript
Javascript中arguments对象的详解与使用方法
Oct 04 Javascript
JavaScript 数组的深度复制解析
Nov 02 Javascript
jQuery 的 ready()的纯js替代方法
Nov 20 Javascript
微信小程序 picker-view 组件详解及简单实例
Jan 10 Javascript
详解AngularJS1.6版本中ui-router路由中/#!/的解决方法
May 22 Javascript
详解vue项目优化之按需加载组件-使用webpack require.ensure
Jun 13 Javascript
详解swipe使用及竖屏页面滚动方法
Jun 28 Javascript
微信小程序开发的基本流程步骤
Jan 31 Javascript
JavaScript判断变量是否为空的自定义函数分享
Jan 31 #Javascript
分享两个手机访问pc网站自动跳转手机端网站代码
Dec 24 #Javascript
js判断登录与否并确定跳转页面的方法
Jan 30 #Javascript
jQuery知识点整理
Jan 30 #Javascript
浅谈jquery回调函数callback的使用
Jan 30 #Javascript
jQuery修改class属性和CSS样式整理
Jan 30 #Javascript
javascript中AJAX用法实例分析
Jan 30 #Javascript
You might like
锁定年轻人的双倍活力 星巴克推出星倍醇即饮浓咖啡
2021/03/03 咖啡文化
php GD绘制24小时柱状图
2008/06/28 PHP
30 个很棒的PHP开源CMS内容管理系统小结
2011/10/14 PHP
对laravel的session获取与存取方法详解
2019/10/08 PHP
JavaScript 面向对象的 私有成员和公开成员
2010/05/13 Javascript
Javascript生成json的函数代码(可以用php的json_decode解码)
2012/06/11 Javascript
ajax不执行success回调而是执行了error回调
2012/12/10 Javascript
js 获取屏幕各种宽高的方法(浏览器兼容)
2013/05/15 Javascript
js左侧三级菜单导航实例代码
2013/09/13 Javascript
js获取对象为null的解决方法
2013/11/21 Javascript
用JQuery实现全选与取消的两种简单方法
2014/02/22 Javascript
js原型继承的两种方法对比介绍
2014/03/30 Javascript
简洁实用的BootStrap jQuery手风琴插件
2016/08/31 Javascript
JS多物体实现缓冲运动效果示例
2016/12/20 Javascript
axios基本入门用法教程
2017/03/25 Javascript
JavaScript基于replace+正则实现ES6的字符串模版功能
2017/04/25 Javascript
vue axios同步请求解决方案
2017/09/29 Javascript
在vue项目中使用Nprogress.js进度条的方法
2018/01/31 Javascript
工作中常用到的ES6语法
2018/09/04 Javascript
如何从头实现一个node.js的koa框架
2019/06/17 Javascript
详解ECMAScript2019/ES10新属性
2019/12/06 Javascript
Windows下安装 node 的版本控制工具 nvm
2020/02/06 Javascript
[41:21]夜魇凡尔赛茶话会 第三期02:看图识人
2021/03/11 DOTA
Python FTP操作类代码分享
2014/05/13 Python
tensorflow模型转ncnn的操作方式
2020/05/25 Python
基于tensorflow for循环 while循环案例
2020/06/30 Python
详解用Python爬虫获取百度企业信用中企业基本信息
2020/07/02 Python
Python2.x与3​​.x版本有哪些区别
2020/07/09 Python
民事和解协议书格式
2014/11/29 职场文书
垂直极限观后感
2015/06/08 职场文书
Python批量将csv文件转化成xml文件的实例
2021/05/10 Python
Django集成富文本编辑器summernote的实现步骤
2021/05/31 Python
python中pandas对多列进行分组统计的实现
2021/06/18 Python
SQL实现LeetCode(196.删除重复邮箱)
2021/08/07 MySQL
Go 通过结构struct实现接口interface的问题
2021/10/05 Golang
Python实现猜拳与猜数字游戏的方法详解
2022/04/06 Python