2

一、同源策略(Same-Origin Policy)

1.1 同源(Same Origin)

协议,域名,端口三者都相同视为同源。同源策略主要是出于安全的考虑。一个源不能访问另一个源的DOM,客户端数据,发生Ajax请求。

1.2 不受同源策略限制的

  1. 跨域资源写入。<script>, <link>, <iframe>, <img>,<video>

  2. 表单提交

1.3 受同源策略限制范围

  1. 跨域脚本API访问(不同源的DOM操作)

  2. 跨域数据存储访问:Cookie,LocalStroage,(?IndexedDB,ApplicationCache,CacheStorage)

  3. Ajax请求

  4. @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>

报错:

clipboard.png

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>

显示:

clipboard.png

2.2.2 优点

A:安全
B:可以传输任何数据类型

2.2.3 缺点

A:这是html5的API,存在兼容性问题。

三、跨域Ajax请求

3.1 受限情况

Ajax请求只能想同源的地址发生请求,否则就报错。

clipboard.png

处理这类情况是可通过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。


普拉斯强
2.7k 声望53 粉丝

Coder


下一篇 »
跨域-CORS