使用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 ...
随机推荐
- 【iOS】TableView的footerView不随cell滚动而停留在tableView底部的问题
苹果官方给我提供TableView的FooterView和HeaderView停留在顶部的非常不错效果,有时候我们不须要这些FooterView和HeaderView停留在底部或者上部,如今就以Foo ...
- 如何设置电脑的固定IP地址
大家在上网时电脑的IP地址往往都是自动选择的,但在局域网内有时会方便共享文件和监控流量等操作时需要固定的IP地址.下面将简单介绍如何手设置电脑的固定IP地址. 百度经验:jingyan.baidu.c ...
- 关于PDNN、Theano、Numpy以及Scipy的安装
最近为了用下PDNN,先得安装这玩意,不装不知道,一装吓一跳,依赖关系也太多了吧,顿时有种贵圈真乱的感觉,如图1. 不过这B还得装下去. 图1 安装PDNN的依赖关系 之前也碰了好多问题,不过各种参考 ...
- C#递归累计到父行
搞了半天 写了一个算法,希望能帮到需要的朋友 效果如下 水电费用是由 就是部门水费和电费累加的,而部门水费由科室水费累加起来的 表结构 DataTable dt = new DataTable(); ...
- Entity Framework应用:使用Code First模式管理事务
一.什么是事务 处理以数据为中心的应用时,另一个重要的话题是事务管理.ADO.NET为事务管理提供了一个非常干净和有效的API.因为EF运行在ADO.NET之上,所以EF可以使用ADO.NET的事务管 ...
- Hibernate- QBC-基本查询
01.环境搭建 02.基本查询 1.方法说明 方法 说明 Restrictions.eq = Restrictions.allEq 利用Map来进行多个等于的限制 Restrictions.gt &g ...
- PHP中动态增加属性到对象
参见: <深入PHP 面向对象.模式与实践>(第三版) [ matt zandstra ] - 3.2章节,设置类中的属性(p17)
- ApplicationEventMulticaster not initialized - call 'refresh' before
https://stackoverflow.com/questions/45318618/applicationeventmulticaster-not-initialized-call-refres ...
- Framework 7 日历插件改成Picker 模式
Framework 7 里面的日历插件默认的2种模式: 1.文本框 2.直接展示 如下图: 更多例子点这里 而我的需求如下图: 点击小图标再弹出日历,选择某个日期,隐藏日历弹层. 实现步骤: 1.写小 ...
- (二)使用预定义模型 QStringListModel例子
使用预定义模型 QStringListModel例子 源代码如下 Main.cpp #include <QApplication> #include "teamleadersdi ...