4. [HTML5] postMessage

问题:

对于跨域问题,研究了一下html5的postMessage,写了代码测试了一下,感觉html5新功能就是好用啊。
此文仅使用html5的新特性postMessage,演示其执行过程和效果:

方法解释:
postMessage()方法允许来自不同源的脚本采用异步方式进行有限的通信,可以实现跨文本档、多窗口、跨域消息传递。
postMessage(data,origin)方法接受两个参数:
1.data:你需要传递的消息,消息传递的格式有一定要求:参数可以是JavaScript的任意基本类型或可复制的对象,然而并不是所有浏览器都做到了这点儿,部分浏览器只能处理字符串参数,所以建议直接传递string类型参数。json格式使用JSON.stringify()方法对对象参数序列化,在低版本IE中引用json2.js可以实现类似效果。
2.origin:该参数指明目标窗口的源。postMessage()方法只会将message传递给指定窗口,也可以设置为"*",表示可以传递给任意窗口。

原理:

1.我的页面是parent.html,接收我发送的消息并按照要求返回消息的页面是child.html;

2.两个页面放在同一个文件夹内;

3.parent.html发送postMessage消息给child.html,child.html收到消息后通过source.postMessage返回所需信息!

具体过程如下:

我的页面是parent.html:

<html>
<div>
<iframe id="child" src="./child.html"></iframe>
</div>
<script type="text/javascript">
window.addEventListener('message',function(e){
alert("msg from child:" + e.data);
});
window.onload=function(){//页面加载完即向iframe发送消息
//var tmp = document.getElementById("child");
//tmp.postMessage('hello babi','*'); //此处tmp没有postMessage方法,类型错误。
//alert(tmp); //这是object HTMLIFrameElement类型
//alert(window.frames[0]); //这是object Window类型
//以上方式不可行,只有window类型才能调用postMessage方法!
window.frames[0].postMessage('hello babi','*');
}
</script>
</html>

中间的文字全都来自child.html!

我们看看接收消息页面child.html:

parent页面向child页面发送了消息,那么在child页面上如何接收消息呢,监听window的message事件就可以

<html>
<p id="ll1">I'm child</p>
<p id="ll2">I'm child</p>
<p id="ll3">I'm child</p>
<p id="ll4">I'm child</p>
<script type="text/javascript">
window.addEventListener('message',function(e){//接收信息后返回信息!
alert("msg from parent:" + e.data);
e.source.postMessage('Hello papi', "*");
});
</script>
</html>

这样我们就可以接收任何窗口传递来的消息了!

我们运行一下:

这样就实现了跨域、跨窗口消息传递

服务器端的跨域方法

一、反向代理服务器

基础思想很简单,将你的服务器配置成 需要跨域获取的资源的 反向代理服务器。

也就是说,将其他域名的资源映射到你自己的域名之下,这样浏览器就认为他们是同源的。

用大家钟爱的 Apache2 来举个例子:

首先启用两个模块 proxy 和 proxy_http 来开启代理功能:

sudo a2enmod proxy
sudo a2enmod proxy_http

然后在配置文件里面写入:

ProxyPass "/foo" "http://foo.example.com/bar"
ProxyPassReverse "/foo" "http://foo.example.com/bar"
  • ProxyPass: 远程服务器在本地服务器的映射。(上面的例子将 http://foo.example.com/bar 映射为 /foo

  • ProxyPassReverse: 配置 Apache2 在 HTTP 跳转时调整 LocationContent-Location 和 URI headers 的值,防止反向代理被绕开。

重启 Apache2:

sudo service apache2 restart

大功告成,这样我们请求 /foo 就会得到 http://foo.example.com/bar 的内容了。

这种方法其实不太常用,机智的读者就会发现,每一个资源都要到自己的服务器配置,每次配置都还要重启。

二、CORS

Cross-Origin Resource Sharing 是 W3C 推出的一种跨站资源获取的机制。

首先我们来看一下浏览器的支持情况:

Chrome Firefox (Gecko) Internet Explorer Opera Safari
4 3.5 8 & 9(XDomainRequest), 10 12 4

移动端的浏览器对这种方法的支持比较完善。现在我们看到了,如果不需要兼容 IE6、7的话,就可以使用这种方法。


这种跨域方案主要的思想是:服务器 在响应头中设置相应的选项,浏览器如果支持这种方法的话就会将这种跨站资源请求视为合法,进而获取资源。

可以设置的响应头信息:

Access-Control-Allow-Origin

Access-Control-Allow-Origin: <origin> | *

origin: 被允许跨域访问这个资源的网站,* 代表全部网站。浏览器会检测这个参数,如果符合要求,才会去获取资源。

举个例子,允许 http://jasonkid.github.io/fezone 来跨域访问这个资源:

Access-Control-Allow-Origin: http://jasonkid.github.io/fezone

Access-Control-Allow-Credentials

Access-Control-Allow-Credentials: true | false

表示是否允许浏览器携带 Cookie 来访问这个资源。
这个属性要和 XMLHttpRequest 的 withCredentials 属性来配合使用。

var xhr = new XMLHttpRequest();
var url = 'http://foo.other/resources/credentialed-content/'; if(xhr) {
xhr.open('GET', url, true);
xhr.withCredentials = true; // 设置带有 Cookie 的资源请求
xhr.onreadystatechange = handler;
xhr.send();
}

能够成功使用带有 Cookie 的资源请求需要满足以下几个条件:

  • XMLHttpRequest 对象中指定了 withCredentials = true

  • 服务器响应头中 Access-Control-Allow-Credentials: true

  • 服务器响应头中 Access-Control-Allow-Origin 不能为 *


以下选项主要是安全性配置的问题,主要是服务器的配置问题了,就不展开介绍了:

  • Access-Control-Expose-Headers

  • Access-Control-Allow-Methods

  • Access-Control-Allow-Headers

跨域问题实践总结!下( [HTML5] postMessage+服务器端(反向代理服务器+CORS Cross-Origin Resource Sharing))的更多相关文章

  1. CORS (Cross Origin Resources Share) 跨域

    CORS 跨域 1 什么是跨域问题 基于安全考虑,浏览器会限制使用脚本发起任何跨域请求. 所谓的跨域请求,就是与当前页面的 http/ip/port 不一样的请求. 但在实际运用中,跨域获取数据的需求 ...

  2. CORS(Cross-origin resource sharing) “跨域资源共享”

    CORS与JSONP的比较 在出现CORS标准之前, 我们还只能通过jsonp的形式去向“跨源”服务器去发送 XMLHttpRequest 请求,这种方式吃力不讨好,在请求方与接收方都需要做处理,而且 ...

  3. ajax跨域访问 java controller 和 cxf(webservice) 配置方式(CORS)

    1. controller跨域访问,配置方式 重点在这里: <mvc:cors> <mvc:mapping path="/*" allowed-origins=& ...

  4. 跨域问题实践总结! 上(JSONP/document.domain/window.name)

    1. JSONP 首先要介绍的跨域方法必然是 JSONP. 现在你想要获取其他网站上的 JavaScript 脚本,你非常高兴的使用 XMLHttpRequest 对象来获取.但是浏览器一点儿也不配合 ...

  5. 基于JWT的web api身份验证及跨域调用实践

    随着多终端的出现,越来越多的站点通过web api restful的形式对外提供服务,很多网站也采用了前后端分离模式进行开发,因而在身份验证的方式上可能与传统的基于cookie的Session Id的 ...

  6. 跨域的另一种解决方案——CORS(Cross-Origin Resource Sharing)跨域资源共享

    在我们日常的项目开发时使用AJAX,传统的Ajax请求只能获取在同一个域名下面的资源,但是HTML5打破了这个限制,允许Ajax发起跨域的请求.浏览器是可以发起跨域请求的,比如你可以外链一个外域的图片 ...

  7. 跨域的另一种解决方案CORS(CrossOrigin Resource Sharing)跨域资源共享

    在我们日常的项目开发时使用AJAX,传统的Ajax请求只能获取在同一个域名下面的资源,但是HTML5打破了这个限制,允许Ajax发起跨域的请求.浏览器是可以发起跨域请求的,比如你可以外链一个外域的图片 ...

  8. (转)跨域的另一种解决方案——CORS(Cross-Origin Resource Sharing)跨域资源共享

    在我们日常的项目开发时使用AJAX,传统的Ajax请求只能获取在同一个域名下面的资源,但是HTML5打破了这个限制,允许Ajax发起跨域的请求.浏览器是可以发起跨域请求的,比如你可以外链一个外域的图片 ...

  9. .net学习之母版页执行顺序、jsonp跨域请求原理、IsPostBack原理、服务器端控件按钮Button点击时的过程、缓存、IHttpModule 过滤器

    1.WebForm使用母版页后执行的顺序是先执行子页面中的Page_Load,再执行母版页中的Page_Load,请求是先生成母版页的控件树,然后将子页面生成的控件树填充到母版页中,最后输出 2.We ...

随机推荐

  1. HBase 运维分析

    问题分析的主要手段 1.监控系统:首先用于判断系统各项指标是否正常,明确系统目前状况 2.服务端日志:查看例如region移动轨迹,发生了什么动作,服务端接受处理了哪些客户端请求. 3.gc日志:gc ...

  2. java的finalize方法使用

    1. finalize的作用 finalize()是Object的protected方法,子类可以覆盖该方法以实现资源清理工作,GC在回收对象之前调用该方法. finalize()与C++中的析构函数 ...

  3. 动态规划:给出两个字符串s1和s2,返回其中最大的公共子串

    求公共子字符串问题(连续的) 这个题目是当时远景能源公司现场笔试的一道题目,当时根本就不知道动态规划是什么鬼,直接上来就暴力求解,面试官很谄媚的问我,你这能求出来吗?当时很年轻的说,能啊!现在想,当时 ...

  4. vue中get和post请求

    import axios from 'axios'; import router from '@/router'; import {     setSessionStorage,     getSes ...

  5. tar结果find打包指定后缀的文件

    find 目录名 -name "*.ini" | xargs tar czvf tarch.tar.gz  tar czf tmp.tar.gz tmp/ --exclude=&q ...

  6. 摘抄详细的VUE生命周期

     Vue所有的生命周期钩子自动绑定在this上下文到实例中,因此你可以访问数据,对属性和方法进行运算.这意味着你不能使用箭头函数来定义一个生命周期方法.这是因为箭头函数绑定了父上下文,因此this与你 ...

  7. Fast Paxos

    http://blog.csdn.net/chen77716/article/details/7297122 自从Lamport在1998年发表Paxos算法后,对Paxos的各种改进工作就从未停止, ...

  8. AngualrJS之服务器端通信

    译自<AngularJS> 与服务器通信 目前,我们已经接触过下面要谈的主题的主要内容,这些内容包括你的Angular应用如何规划设计.不同的angularjs部件如何装配在一起并正常工作 ...

  9. log4j2.xml全配置文件

    可以参考如下配置 <?xml version="1.0" encoding="UTF-8"?> <!--日志级别以及优先级排序: OFF &g ...

  10. ES6浅谈之Promise

    首先来回想一下Promise对象的写法: // 方法1 let promise = new Promise ( (resolve, reject) => { if ( success ) { . ...