同源策略
源:由协议【https、http】+域名【a.com】+端口【80、443】组成,(ie中略有不同),同源策略是浏览器的核心安全策略,目的是将来自不同源的资源进行隔离,并控制不同源资源间的通信,从而减少安全威胁,增强安全性。
跨域中的一些限制以及不限制内容如下:
不限制内容:
- 脚本文件 js
- 图片资源
- 样式资源css
- iframe展示其他的的资源
- a链接访问其他资源
- 多媒体等资源
- form表单提交
限制内容:
- 跨域的方法【get、post可以】
- 跨域请求头不可以添加自定义头部
- 本地文件系统读写
- iframe可以访问iframe整体,不能访问内容
- cookie的限制,使用CORS需要withCredentials=true才可以带上cookie
========================================================
一、同源策略
1、何为同源?
所谓"同源"指的两个网页url的三个部分是相同的:
http://www.example.com:80/dir/page.html
协议相同
域名相同
端口相同
2、同源策略
同源策略是Web应用程序安全模型中的一个重要概念,它由 Netscape 公司在1995年引入浏览器。该策略最初是为保护DOM的访问而设计的,Web浏览器允许第一个Web页面中包含的脚本访问第二个Web页面中的数据,但前提是两个Web页面具有相同的origin。后来进行了扩展,此策略可防止一个页面上的恶意脚本通过该页面的DOM访问另一个网页上的敏感数据。这一机制对于广泛依赖HTTP cookie来维护经过身份验证的用户会话的现代Web应用程序具有特别的意义,因为服务器基于HTTP cookie信息来显示敏感信息或采取状态更改操作。必须在客户端保持无关站点提供的内容之间的严格分离,以防止数据机密性或完整性丢失。
同源策略主要应用于从脚本访问数据;通过相应的HTML标记嵌入跨源的资源,如图像、CSS和脚本不受限制
3、实现
因为它是一个重要的安全基石,所有现代浏览器都实现某种形式的同源策略,这些策略不需要与精确的规范相匹配,但通常被扩展为与其他Web技术(如Microsoft Silverlight、Adobe Flash或Adobe Acrobat或M)定义大致兼容的安全边界。
4、同源策略的限制
(1) Cookie、LocalStorage 和 IndexDB 无法读取
(2) DOM 无法获得
(3) AJAX 请求不能发送
二、绕过同源策略限制的方法
1、document.domain属性
Cookie 是服务器写入浏览器的一小段信息,只有同源的网页才能共享。但是,两个网页一级域名相同,只是二级域名不同,浏览器允许通过设置document.domain共享 Cookie。
1.1、通过JS设置document.domain属性:
<script type="text/javascript">
document.domain = 'example.com';
</script>
1.2、服务器也可以在设置Cookie的时候,指定Cookie的所属域名为一级域名,比如.example.com。
Set-Cookie: key=value; domain=.example.com; path=/
这样的话,二级域名和三级域名不用做任何设置,都可以读取这个Cookie。
2、片段识别符(fragment identifier)
片段标识符(fragment identifier)指的是,URL的#号后面的部分,比如http://example.com/x.html#fragment的#fragment
当fragment变化的时候,会触发window.onhashchange事件,可以通过修改片段标识符的值,来在两个页面之间传递数据
父窗口可以把信息,写入子窗口的片段标识符。
var src = originURL + '#' + data;
document.getElementById('myIFrame').src = src;
子窗口通过监听hashchange事件得到通知。
window.onhashchange = checkMessage;
function checkMessage() {
var message = window.location.hash;
// ...
}
同样的,子窗口也可以改变父窗口的片段标识符:
parent.location.href= target + "#" + hash;
3、window.name
4、跨文档通信API(Cross-document messaging)
5、JSONP
6、CORS(Cross-Origin Resource Sharing)
7、WebSockets
三、JSONP和CORS两种跨域方式的对比:
3.1、JSONP
JSONP是利用浏览器对script的资源引用没有同源限制,通过动态插入一个script标签,当资源加载到页面后会立即执行的原理实现跨域的。JSONP是一种非正式传输协议,该协议的一个要点就是允许用户传递一个callback或者开始就定义一个回调方法,参数给服务端,然后服务端返回数据时会将这个callback参数作为函数名来包裹住JSON数据,这样客户端就可以随意定制自己的函数来自动处理返回数据了。
JSONP只支持GET请求而不支持POST等其它类型的HTTP请求,它只支持跨域HTTP请求这种情况,不能解决不同域的两个页面之间如何进行JavaScript调用的问题,JSONP的优势在于支持老式浏览器,弊端也比较明显:需要客户端和服务端定制进行开发,服务端返回的数据不能是标准的Json数据,而是callback包裹的数据。
3.2、CORS
CORS是现代浏览器支持跨域资源请求的一种方式,当使用XMLHttpRequest发送请求时,浏览器发现该请求不符合同源策略,会给该请求加一个请求头:Origin,后台进行一系列处理,如果确定接受请求则在返回结果中加入一个响应头:Access-Control-Allow-Origin;浏览器判断该相应头中是否包含Origin的值,如果有则浏览器会处理响应,我们就可以拿到响应数据,如果不包含浏览器直接驳回,这时我们无法拿到响应数据。
CORS支持所有的浏览器请求类型,承载的请求数据量更大,开放更简洁,服务端只需要将处理后的数据直接返回,不需要再特殊处理。