跨域问题实践总结!下( [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/fezoneAccess-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 ... 
随机推荐
- 【Qt编程】基于Qt的词典开发系列<四>--无边框窗口的缩放与拖动
			在现在,绝大多数软件都向着简洁,时尚发展.就拿有道的单词本和我做的单词本来说,绝大多数用户肯定喜欢我所做的单词本(就单单界面,关于颜色搭配和布局问题,大家就不要在意了). 有道的单词本: 我所做的单词 ... 
- disable table 失败的处理
			相信每一个维护hbase集群的运维人员一定碰到过disable失败,陷入无穷的"Region has been PENDING_CLOSE for too long..."状态,此 ... 
- iOS苹果自带UIMenuController
			一.UIMenuController认识 1.默认情况下,UITextView / UITextFiled / UIWebView 都有苹果自带的有UIMenuController功能 2.UITex ... 
- Day2_元组_字典_集合_字符编码_文件处理
			元组: 作用:存多个值,元组不可变,主要用来读 age=(11,22,33,44,55) print(age[2]) #取出元组内的值 print(age[1:4]) #取出元组内的某些值 print ... 
- springboot + mybatis  前后端分离项目的搭建  适合在学习中的大学生
			人生如戏,戏子多半掉泪! 我是一名大四学生,刚进入一家软件件公司实习,虽说在大学中做过好多个实训项目,都是自己完成,没有组员的配合.但是在这一个月的实习中,我从以前别人教走到了现在的自学,成长很多. ... 
- How to change from default to alternative Python version on Debian Linux
			https://linuxconfig.org/how-to-change-from-default-to-alternative-python-version-on-debian-linux You ... 
- Django代码注意
			1.模板标签里面 extend和include是冲突的,有了extend,include无法生效,原因:是底层渲染独立机制设计导致. 2.#coding:utf-8 这句只有放在代码文件第一行才能生效 ... 
- Android开发阅读文档资源
			Android Studio:工具:http://developer.android.com/intl/zh-cn/tools/studio/index.html培训教程:http://develop ... 
- Hbase出现ERROR: Can't get master address from ZooKeeper; znode data == null解决办法
			问题描述如下: hbase(main)::> list TABLE ERROR: Can't get master address from ZooKeeper; znode data == n ... 
- 拖拽模块move1
			刚开的博客,想着写点什么,以前写过拖拽函数,后来又学习了模块化,于是一直想把之前写的拖拽函数封成一个独立的模块,方便以后调用,说干就干,下面码代码... <script> var move ... 
