使用HTML5 的跨域通信机制进行数据同步
离线应用系统的设计目标就是在网络离线情况下依然可以操作我们的应用系统,并在网络畅通的情况下与服务器进行数据交互。
所以离线应用系统最终会做成类似C/S架构的客户端应用程序。这边基于Chrome或者 Safari浏览器的 Web Application(Web 应用程序插件)无疑是最好的选择。
这边以Chrome 的 Web Application 为例,离线系统做成Web 应用程序之后,与服务端的交互就变成最麻烦的一件事了,因为离线Web应用程序是安装在各个用户的浏览器上面,而最终的Server,只是一个由终端服务方提供的固定地址。那么从本地浏览器对Server发起请求,就存在这跨域通信的情况。
JavaScript出于安全方面的考虑,不允许跨域调用其他页面的对象。因为同源策略的限制,域名www.xx1.com下的js无法访问和操作www.xx2.com域名下的对象。
下面是一个关于跨域访问的说明清单,摘自博客园的一篇文章:
URL |
说明 |
是否允许通信 |
http://www.a.com/a.js |
同一域名下 |
允许 |
http://www.a.com/lab/a.js |
同一域名下不同文件夹 |
允许 |
http://www.a.com:8000/a.js |
同一域名,不同端口 |
不允许 |
http://www.a.com/a.js |
同一域名,不同协议 |
不允许 |
http://www.a.com/a.js |
域名和域名对应ip |
不允许 |
http://www.a.com/a.js |
主域相同,子域不同 |
不允许 |
http://www.a.com/a.js |
同一域名,不同二级域名(同上) |
不允许 (cookie这种情况下也不允许访问) |
http://www.cnblogs.com/a.js |
不同域名 |
不允许 |
HTML5提供了跨文档消息机制(Cross Document Messaging),它具备了跨越frame、tabs或windows通信的能力。
PostMessage API
window.postMessage是安全启用跨域通信的方法。通常情况下,不同的页面上的脚本只允许相互访问和执行他们的网页,window.postMessage提供了一个控制机制,以规避此限制的方式是安全的。
浏览器支持情况:
浏览器类型 |
版本号 |
Chrome |
2.0版本及以上 |
FireFox |
3.0版本及以上 |
Internet Explorer |
8.0版本及以上 |
Opera |
9.6版本及以上 |
Safari |
4.0版本及以上 |
数据发送方:otherWindow.postMessage(message, targetOrigin);
otherWindow
对另一个窗口的引用,这边可以使用的contentWindow属性的iframe元素,或通过window.open返回的对象,或通过frames命名window.frames。
message
发送到其它窗口的数据。
targetOrigin
数据发送的目标地址。
数据接收方:
window.addEventListener("message", receiveMessage, false);
function receiveMessage(event)
{ if (event.origin !== "http://XXXX") return;
// ... }
event.data
获取从其他窗口传输过来的数据对象。
event.origin
postMessage的发送消息时的窗口的起源。这个字符串是该协议的串联和“:/ /”,主机名(如果有的话),和“:”如果一个端口,并从给定的协议的默认端口不同的端口号。
event.source
一个窗口之间建立双向沟通两个不同来源的窗户,代表了你目前的接收方的窗口,你可以使用这个对象发送消息。
我们离线系统中的Information.htm页面保存的是当前登录用户的相关信息,假设现在的网络是在线情况下,那我们的保存功能就需要同步保存到服务端。所以我们的Information.htm页面除了保存之外,还多了跨域通讯相关实现代码。
同样的,我们也需要一个跨域访问的服务端,那我们就做个服务端,设计数据库如下:
这个表的设计是相对于我们客户端的数据表,用来保存或者修改客户端提交上来的数据。然后我们在服务端写好与之相关的操作就行了。服务端这边也要建立一个页面:crossDomain.htm,作为跨域访问的源(附件源码中有关于服务端这块的代码)。在crossDomain.htm页面里面我们写好程序处理客户端传递过来的值。
代码如下:
现在我们来看一下发起跨域请求的页面是怎么写的,写在我们的Information.htm页面里。
首先,我们加一个iframe元素,用来链接我们跨域交互的那个页面,然后我们获取那个iframe的contentWindow,并以它为源来发送信息。
"http://192.168.21.22:86/CRXServer/crossDomain.htm":假设这个地址则是我们服务端页面的所在地址,这样子,我们就把表单的数据发送过去了。
代码如下:
服务端接收到表单数据之后,进行了数据处理,处理完成之后反馈信息到发送端(也就是我们发起请求的客户端),我们的发送端接收到信息,并进行处理,所以发送端这边还需要加一个监听事件:
一旦监听到服务端向我们返回数据,我们就输出数据。
这样,流程环节就出来了:
提交保存之后,我们会弹出一个对话框,显示“保存成功!”,那显示的是服务端返回的数据,同时,数据库中也保存进了数据。
关于XMLHttpRequest Level 2
HTML5中定义了XMLHttpRequest Level 2,它有两方面的增强:跨域通信,通信进度通知(progress events),有兴趣的可以了解下:
http://www.html5rocks.com/en/tutorials/file/xhr2/
关于Chrome Web Application(chrome Web 应用程序插件)中的跨域:
{
"name": "My extension",
...
"permissions": [
"http://192.168.21.22/"
],
...
}
这样就可以直接在插件里面的脚本中访问服务端的数据,当然安全性方面需要设置,这些我们会在后面的Chrome Web Application章节里详细了解。
使用HTML5 的跨域通信机制进行数据同步的更多相关文章
- Html5 跨域通信
H5 跨域通信: 在主页面中通过iframe嵌入外部页面,通过iframe的window对象postMessage方法向iframe页面传递消息. 1 <!DOCTYPE html> 2 ...
- 利用HTML5的window.postMessage实现跨域通信
详见: http://blog.yemou.net/article/query/info/tytfjhfascvhzxcytp77 HTML5的window.postMessage简述 postM ...
- html5 postMessage解决iframe跨协议跨域通信问题
a.html有个iframe载入b.com/login.html,当login完成时通知a.html页面登录完成并传递UserName 1.a.html 监听消息 window.addEventLis ...
- JavaScript系列----AJAX机制详解以及跨域通信
1.Ajax 1.1.Ajax简介 Ajax简介这一部分我们主要是谈一下ajax的起源,ajax是什么?因为这些是跟技术无关的.所以,大多细节都是一笔带过. Ajax的起源? Ajax一词源于2005 ...
- iframe跨域通信方案
概述 JavaScript出于安全方面的考虑,不允许跨域调用其他页面的对象.但在安全限制的同时也给注入iframe或是ajax应用上带来了不少麻烦.这里把涉及到跨域的一些问题简单地整理一下: 首先什么 ...
- JavaScript 跨域:window.postMessage 实现跨域通信
JavaScript 跨域方式实现方式有很多,之前,一篇文章中提到了 JSONP 形式实现跨域.本文将介绍 HTML5 新增的 api 实现跨域:window.postMessage . 1 othe ...
- 【JavsScript】父子页面之间跨域通信的方法
由于同源策略的限制,JavaScript跨域的问题,一直是一个比较棘手的问题,为了解决页面之间的跨域通信,大家煞费苦心,研究了各种跨域方案.之前也有小网同学分享过一篇“跨域,不再纠结” 开始照着尝试时 ...
- 【JavaScript】父子页面之间跨域通信的方法
由于同源策略的限制,JavaScript跨域的问题,一直是一个比较棘手的问题,为了解决页面之间的跨域通信,大家煞费苦心,研究了各种跨域方案.之前也有小网同学分享过一篇“跨域,不再纠结” 开始照着尝试时 ...
- 使用window.postMessage实现跨域通信
JavaScript由于同源策略的限制,跨域通信一直是棘手的问题.当然解决方案也有很多: document.domain+iframe的设置,应用于主域相同而子域不同: 利用iframe和locati ...
随机推荐
- mysql 2013错误解决
今天,莫名其妙的来了个mysql 2013错误,导致无法登陆mysql gui工具,而且dos也进不去,提示ping 127.0.0.1,百度+google后: 这是在使用 mysql 的过程中,困扰 ...
- SO_REUSEADDR的作用
服务器socketstreamtcpc 原贴地址:http://topic.csdn.net/u/20090103/16/a0414edb-b289-4c72-84da-39e155e8f4be.ht ...
- java中常见的异常(转)
1. java.lang.nullpointerexception 这个异常大家肯定都经常遇到,异常的解释是"程序遇上了空指针",简单地说就是调用了未经初始化的对象或者是不存在的对 ...
- C#操作word类文件
最近频繁操作Word文档,写了很多word的操作代码及方法,虽然已经有很多关于word的操作类了,自己还是进行了一下整合: 1.通过模板创建新文件 2.在书签处插入值 3.插入表格 4.合并单元格 5 ...
- C#递归累计到父行
搞了半天 写了一个算法,希望能帮到需要的朋友 效果如下 水电费用是由 就是部门水费和电费累加的,而部门水费由科室水费累加起来的 表结构 DataTable dt = new DataTable(); ...
- EasyUi---searchbox 条件查询
前台UI参考代码: <script type="text/javascript" charset="utf-8"> $(function(){ /* ...
- jquery-easyui 中表格的行编辑功能
具体实现代码如下: <table id="tt"></table> $('#tt').datagrid({ title:'Editable DataGrid ...
- 关于Cocos2d-x有些头文件无法引入或者类显示无法打开
选中工程右键“属性”->"配置属性“->"c/c++"->"常规”->"附加包含目录"中添加“”$(EngineRo ...
- 第二百八十二节,MySQL数据库-MySQL视图
MySQL数据库-MySQL视图 1.视图是一个虚拟表(非真实存在),其本质是[根据SQL语句获取动态的数据集,并为其命名],用户使用时只需使用[名称]即可获取结果集,并可以将其当作表来使用. 2.也 ...
- MongoDB状态查询:db.serverStatus()
参见:http://www.2cto.com/database/201501/370191.html 基本信息 spock:PRIMARY>db.serverStatus() { "h ...