使用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 ...
随机推荐
- 深入学习RabbitMQ(四):channel的confirm模式
转自:http://m.blog.csdn.net/article/details?id=54340711 上一篇博客我们介绍了使用RabbitMQ可能会遇到的一个问题,即生产者不知道消息是否真正到达 ...
- Java并发(四)多线程开销
从单线程应用转变为多线程应用并不只是带来好处.这种转变也会带来一定得开销得.并不是所有时候都要把你的应用编程多线程的.你应该明白这样做确实会带来好处,而且这种好处要比开销大.如果你不确定的话,要试着去 ...
- [4G]Linux平台上实现4G通信
转自:http://blog.sina.com.cn/s/blog_7880d3350102wb92.html 在ARM平台上实现4G模块的PPP拨号上网,参考网上的资料和自己的理解,从一无所知到开发 ...
- git关联远程仓库命令<原>
一.存在远程仓库了,本地想克隆其代码: $ git clone git@git.oschina.net:winkey4986/Weather_demo.git 二.本地有代码了,想在建个远程仓库保存代 ...
- 4G模块ME3760_V2的拨号过程
AT AT+CFUN=1 模块功能全打开,上电可以设置默认状态 AT+ZSET="LET_INFO" 掉电后可以保存AT+CFUN ...
- Android——TextView属性XML详解
Android_TextView属性XML详解 博客分类: android 属性名称 描述 android:autoLink 设置是否当文本为URL链接/email/电话号码/map时 ...
- 利用Nginx搭建RTMP视频直播,点播服务器,ffmpeg推流,回看
一.环境和工具 ubuntu 14.04 desktop 不用server的原因是一部分的演示用到了linux视频播放和直播软件,自己还要装桌面,麻烦. 不建议使用 最新的16TLS,我一开始 ...
- 用jQuery屏蔽掉按回车键时提交表单
<script type="text/javascript"> $(function() { $("input").keypress(functio ...
- 科技发烧友之3d吉米投影
http://item.jd.com/1558081.html?r=1434635270480#comment 暴风199的墨镜
- 监视在input框中按下回车(enter) js实现
function getKey(event) { if (event.keyCode == 13) { alert("我是回车键"); } } <input type=&qu ...