跨域问题实践总结!下( [HTML5] postMessage+服务器端(反向代理服务器+CORS Cross-Origin Resource Sharing))
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 跳转时调整Location,Content-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))的更多相关文章
- CORS (Cross Origin Resources Share) 跨域
CORS 跨域 1 什么是跨域问题 基于安全考虑,浏览器会限制使用脚本发起任何跨域请求. 所谓的跨域请求,就是与当前页面的 http/ip/port 不一样的请求. 但在实际运用中,跨域获取数据的需求 ...
- CORS(Cross-origin resource sharing) “跨域资源共享”
CORS与JSONP的比较 在出现CORS标准之前, 我们还只能通过jsonp的形式去向“跨源”服务器去发送 XMLHttpRequest 请求,这种方式吃力不讨好,在请求方与接收方都需要做处理,而且 ...
- ajax跨域访问 java controller 和 cxf(webservice) 配置方式(CORS)
1. controller跨域访问,配置方式 重点在这里: <mvc:cors> <mvc:mapping path="/*" allowed-origins=& ...
- 跨域问题实践总结! 上(JSONP/document.domain/window.name)
1. JSONP 首先要介绍的跨域方法必然是 JSONP. 现在你想要获取其他网站上的 JavaScript 脚本,你非常高兴的使用 XMLHttpRequest 对象来获取.但是浏览器一点儿也不配合 ...
- 基于JWT的web api身份验证及跨域调用实践
随着多终端的出现,越来越多的站点通过web api restful的形式对外提供服务,很多网站也采用了前后端分离模式进行开发,因而在身份验证的方式上可能与传统的基于cookie的Session Id的 ...
- 跨域的另一种解决方案——CORS(Cross-Origin Resource Sharing)跨域资源共享
在我们日常的项目开发时使用AJAX,传统的Ajax请求只能获取在同一个域名下面的资源,但是HTML5打破了这个限制,允许Ajax发起跨域的请求.浏览器是可以发起跨域请求的,比如你可以外链一个外域的图片 ...
- 跨域的另一种解决方案CORS(CrossOrigin Resource Sharing)跨域资源共享
在我们日常的项目开发时使用AJAX,传统的Ajax请求只能获取在同一个域名下面的资源,但是HTML5打破了这个限制,允许Ajax发起跨域的请求.浏览器是可以发起跨域请求的,比如你可以外链一个外域的图片 ...
- (转)跨域的另一种解决方案——CORS(Cross-Origin Resource Sharing)跨域资源共享
在我们日常的项目开发时使用AJAX,传统的Ajax请求只能获取在同一个域名下面的资源,但是HTML5打破了这个限制,允许Ajax发起跨域的请求.浏览器是可以发起跨域请求的,比如你可以外链一个外域的图片 ...
- .net学习之母版页执行顺序、jsonp跨域请求原理、IsPostBack原理、服务器端控件按钮Button点击时的过程、缓存、IHttpModule 过滤器
1.WebForm使用母版页后执行的顺序是先执行子页面中的Page_Load,再执行母版页中的Page_Load,请求是先生成母版页的控件树,然后将子页面生成的控件树填充到母版页中,最后输出 2.We ...
随机推荐
- Mybatis的resultType
使用mybatis去查询数据时,没有指定resultType,mybatis无法返回正常结果,当然在web中并没有出现报错,所以有点坑自己了,所以需要使用如下配置: <select id=&qu ...
- erlang在redhat上的安装
erlang在redhat上的安装 1) 下载源码包: http://www.erlang.org/download/otp_src_17.3.tar.gz 2) RHEL6.4预安装包 $ yum ...
- 【Android 应用开发】Activity生命周期 与 Activity 之间的通信
一. Activity生命周期 上图 1. Activity状态 激活状态 : Activity出于前台 , 栈顶位置; 暂停状态 : 失去了焦点 , 但是用户仍然可以看到 , 比如弹出一个对话框 , ...
- How tomcat works 读书笔记十二 StandardContext 上
在tomcat4中,StandardContext.java是最大的一个类,有117k.废话不说,开始分析吧. 其实要分析StandardContext,也就主要分析两个方法,一个start,一个in ...
- 安卓系统启动脚本init.rc说明文件readme.txt翻译
本说明文件位于system/core/init/readme.txt 本文参考深入解析安卓系统一书,进行翻译,版权部分归书的作者 刘超,资深Android专家,系统架构师. 博客地址:http:// ...
- The 3rd tip of DB QueryAnalyzer
The 3rd tip of DB Query Analyzer Ma Genfeng (Guangdong Unitoll Services incorporated, Guangzhou 510 ...
- jQuery插件之----缓冲运动
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/ ...
- react中需要用到【深度复制】的问题
首先,说一下我所遇到的问题,我所做的项目是用的基于react的antd框架. 一张表格,里面的数据是从后台获取直接渲染,我点击修改按钮,在modal弹框中修改数据,但是没有点击确定,点击取消,发现页面 ...
- werfault进程使用CPU率高
werfault进程是Windows vista 错误报告进程,是用来向微软反馈报告.是安全的正常进程. 解决方法:1.打开控制面板”—“系统和维护”,点击“问题报告和解决方案”. 2.点击“更改设置 ...
- Web开发相关工具收集
FireFox相关: FireBug/GreaseMonkey/Yslow/WebDeveloperSelenium:Web应用程序测试的工具-- http://seleniumhq.org/ h ...