一、同源策略(Same-Origin Policy)
1.1 同源(Same Origin)
协议,域名,端口三者都相同视为同源。同源策略主要是出于安全的考虑。一个源不能访问另一个源的DOM,客户端数据,发生Ajax请求。
1.2 不受同源策略限制的
跨域资源写入。<script>, <link>, <iframe>, <img>,<video>
表单提交
1.3 受同源策略限制范围
跨域脚本API访问(不同源的DOM操作)
跨域数据存储访问:Cookie,LocalStroage,(?IndexedDB,ApplicationCache,CacheStorage)
Ajax请求
@font-face(部分浏览器,如Gecko)
二、跨域脚本API访问
2.1 限制情况
JS中可以通过iframe.contentWindow, window.open, window.opener, window.parent等API进行文档间的交互。但这只限于同源文档之间,非同源之间不能交互。
页面A:http://qyao.com/CookieOperati...
<!DOCTYPE html>
<html>
<head>
<title>Index</title>
</head>
<body>
<iframe id="so" src="http://qyao.m.ctrip.com/CookieOperation/home/detail" height="200" width="300"></iframe>
<input type="button" id="pm" value="Post Message" />
</body>
</html>
<script type="text/javascript">
document.addEventListener('DOMContentLoaded', function () {
var btn = document.getElementById('pm');
btn.addEventListener('click', function () {
var detaiDoc = document.getElementById('so').contentWindow.document; // 访问so窗口的document
});
});
</script>
报错:
2.2 window.postMessage
2.2.1 介绍
Html5中引入了一个新的API: window.postMessage,可以安全的使不同源文档通信。
分别修改A,B页面内容
A页面:
<!DOCTYPE html>
<html>
<head>
<title>Index</title>
</head>
<body>
<iframe id="so" src="http://qyao.m.ctrip.com/CookieOperation/home/detail" height="200" width="300"></iframe>
<input type="button" id="pm" value="Post Message" />
</body>
</html>
<script type="text/javascript">
document.addEventListener('DOMContentLoaded', function() {
var btn = document.getElementById('pm');
btn.addEventListener('click', function () {
var detaiWin = document.getElementById('so').contentWindow;
console.log('Index: hi, What\' your title ?');
detaiWin.postMessage({ title: document.title }, 'http://qyao.m.ctrip.com');
});
});
window.addEventListener('message', function (e) {
console.log('Index: hi ' + e.data.title);
});
</script>
B页面:
<!DOCTYPE html>
<html>
<head>
<title> Detail</title>
</head>
<body>
<h2>Detail</h2>
</body>
</html>
<script type="text/javascript">
window.addEventListener('message', function (e) {
console.log('Detai: hi ' + e.data.title + '. I\'m Detail.');
e.source.postMessage({ title: document.title }, '*');
});
</script>
显示:
2.2.2 优点
A:安全
B:可以传输任何数据类型
2.2.3 缺点
A:这是html5的API,存在兼容性问题。
三、跨域Ajax请求
3.1 受限情况
Ajax请求只能想同源的地址发生请求,否则就报错。
处理这类情况是可通过JSONP,CORS方式解决。
3.2 JSONP
参考:
CSDN:http://www.ibm.com/developerworks/cn/web/wa-aj-jsonp1/index.html
JSONP其实是解决异步跨域请求的问题,跟AJAX半毛钱关系都没有。
3.2.1 原理
script标签不受同源策略约束,即src属性的值可以是非同源地址。把请求的接口地址和参数通过URL的方式添加到一个script标签的src属性上,接口处理完成后返回个JS函数调用语句字符串。这样就实现了异步跨域请求接口。
3.2.2 怎么做
A:Client端script标签的src属性指向服务的地址
B:服务端返回JS回调函数调用语句的字符串。回调函数名一般是客户端传过来的,或者前后端约定的回调函数名。
3.2.3 缺点
A:只支持GET请求。
3.2.4 优点
A:所有的浏览器都支持
3.3 CORS
CORS是解决该问题的终极方案
四、跨域数据存储访问
4.1 受限情况
存储在浏览器中的数据,如localStorage和IndexedDB,以源进行分割。每个源都拥有自己单独的存储空间,一个源中的Javascript脚本不能对属于其它源的数据进行读写操作。
处理这种情况是可通过window.postMessage方式解决。
4.2 window.postMessage
postMessage实现了两个不同源的页面间通信,可以用来解决跨域数据访问问题。
4.3 特殊的Cookie
Cookie关于源的定义不同,参考C_Cookie。
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。