离线应用系统的设计目标就是在网络离线情况下依然可以操作我们的应用系统,并在网络畅通的情况下与服务器进行数据交互。

所以离线应用系统最终会做成类似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/b.js

同一域名下

允许

http://www.a.com/lab/a.js
http://www.a.com/script/b.js

同一域名下不同文件夹

允许

http://www.a.com:8000/a.js
http://www.a.com/b.js

同一域名,不同端口

不允许

http://www.a.com/a.js
https://www.a.com/b.js

同一域名,不同协议

不允许

http://www.a.com/a.js
http://70.32.92.74/b.js

域名和域名对应ip

不允许

http://www.a.com/a.js
http://script.a.com/b.js

主域相同,子域不同

不允许

http://www.a.com/a.js
http://a.com/b.js

同一域名,不同二级域名(同上)

不允许

(cookie这种情况下也不允许访问)

http://www.cnblogs.com/a.js
http://www.a.com/b.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 的跨域通信机制进行数据同步的更多相关文章

  1. Html5 跨域通信

    H5 跨域通信: 在主页面中通过iframe嵌入外部页面,通过iframe的window对象postMessage方法向iframe页面传递消息. 1 <!DOCTYPE html> 2 ...

  2. 利用HTML5的window.postMessage实现跨域通信

    详见: http://blog.yemou.net/article/query/info/tytfjhfascvhzxcytp77   HTML5的window.postMessage简述 postM ...

  3. html5 postMessage解决iframe跨协议跨域通信问题

    a.html有个iframe载入b.com/login.html,当login完成时通知a.html页面登录完成并传递UserName 1.a.html 监听消息 window.addEventLis ...

  4. JavaScript系列----AJAX机制详解以及跨域通信

    1.Ajax 1.1.Ajax简介 Ajax简介这一部分我们主要是谈一下ajax的起源,ajax是什么?因为这些是跟技术无关的.所以,大多细节都是一笔带过. Ajax的起源? Ajax一词源于2005 ...

  5. iframe跨域通信方案

    概述 JavaScript出于安全方面的考虑,不允许跨域调用其他页面的对象.但在安全限制的同时也给注入iframe或是ajax应用上带来了不少麻烦.这里把涉及到跨域的一些问题简单地整理一下: 首先什么 ...

  6. JavaScript 跨域:window.postMessage 实现跨域通信

    JavaScript 跨域方式实现方式有很多,之前,一篇文章中提到了 JSONP 形式实现跨域.本文将介绍 HTML5 新增的 api 实现跨域:window.postMessage . 1 othe ...

  7. 【JavsScript】父子页面之间跨域通信的方法

    由于同源策略的限制,JavaScript跨域的问题,一直是一个比较棘手的问题,为了解决页面之间的跨域通信,大家煞费苦心,研究了各种跨域方案.之前也有小网同学分享过一篇“跨域,不再纠结” 开始照着尝试时 ...

  8. 【JavaScript】父子页面之间跨域通信的方法

    由于同源策略的限制,JavaScript跨域的问题,一直是一个比较棘手的问题,为了解决页面之间的跨域通信,大家煞费苦心,研究了各种跨域方案.之前也有小网同学分享过一篇“跨域,不再纠结” 开始照着尝试时 ...

  9. 使用window.postMessage实现跨域通信

    JavaScript由于同源策略的限制,跨域通信一直是棘手的问题.当然解决方案也有很多: document.domain+iframe的设置,应用于主域相同而子域不同: 利用iframe和locati ...

随机推荐

  1. samba实现跨平台文件共享

    前言:Linux/Unix主机之间实现文件共享我们可以使用NFS,那么,Linux/Unix和Windows主机之间共享文件怎么实现呢,samba就是解决这个问题的. Windows网上邻居依赖的协议 ...

  2. 【C++程序员学 python】python 之变量

    既然学过C++,那么就应该知道变量是什么,常量是什么. python 相比于C++,在使用变量之前不用先声明. 而是直接使用,python 会根据你的变量自动识别其类型. 假如a = 123 那么a ...

  3. 在java web中获取该项目的根路径

    在jsp页面中: <% String path = application.getRealPath("").replace("\\","\\\\ ...

  4. egret请求参数

    egret的文档还不错,不过http请求参数的文档居然没有,于是自己摸索了一下, 发现原来是直接传字符串参数就可以了.于是封装了一个类,方便使用. class RequestParam { publi ...

  5. 接Window服务(二)

    接Window服务(一) ServiceController方法调用 1 public partial class Service1 : ServiceBase 2 { 3 public Servic ...

  6. linux下获取服务器硬件信息的脚本

    这是个简单的脚本,便于查询服务器的硬件信息: #!/bin/bash # # Description: # Used to get the hardware config information. # ...

  7. Timsort 算法

    转载自:http://blog.csdn.net/yangzhongblog/article/details/8184707 Timsort是结合了合并排序(merge sort)和插入排序(inse ...

  8. rufus/scheduler

    之前先在initializers 文件夹下建立了一个task.rb ,rails服务启动的时候执行,本地没问题,可是服务器上启动了3个进程,会执行3遍,解决方法是 把task.rb 放到 script ...

  9. MySql C++调用库Connector/c++编译 和 接口封装【三】Connector/c++ 使用总结及封装

    工程需要加上各个路径: 库使用需要几个文件: 1.include 文件夹 c/c++ /常规/附加包含目录 Connector/c++ 的安装版里面的Include 文件夹.或者把 /driver以及 ...

  10. daterangepicker 使用方法总结

    daterangepicker 是一个时间段选择插件.官网地址:http://www.daterangepicker.com/ 项目中需要实现如下图的效果: 1.引入该插件所需要的JS 和 CSS , ...