跨域是指从一个域名的网页去访问另外一个域名的网页。一个完整URL地址一般由 协议+主机+端口+路径[+hash或search] 组成,其中hash和search是可选项、协议未列出则默认为http、port未列出则默认为80值。所以严格来讲,两个网页地址的协议(http/https)、主机、端口三者任何一个不一样就能够认为是跨域访问,即便两个地址是不一样子域名也是跨域,如app.baidu.com与baidu.com。javascript
浏览器出于安全考虑会限制跨域访问(即同源策略)。在该限制下,除非两个网页是来自于同一‘源头’, 不然不容许一个网页的JavaScript访问另一个网页的内容,像Cookie,DOM,LocalStorage均禁止访问;但对具备src属性的标签(如script、img、iframe等)不作跨域限制。html
浏览器出于安全考虑会限制跨域访问,若不加限制则在一个站点上访问后本地存储的cookie等信息在访问第二个站点时就可能泄露了。(从这可见,跨域限制只是在经过浏览器访问时才存在,所以经过HTTP客户端等访问显然没有跨域限制问题)前端
没有同源限制时的危害示例:java
在浏览器上先登陆股票网站www.stock.com,获得了cookie,之后再访问stock时浏览器会自动带上cookie;接着访问恶意网站www.beautify.com,假定该网站页面中包含一个恶意js脚本,其行为是去访问stock并把获得的信息发到beautify网站,因为访问stock时浏览器会自动带上cookie故恶意脚本能够成功窃取到数据。示意图以下:ajax
上述过程就是跨站请求伪造(Cross-site request forgery,CSRF)的一种例子,所幸在有浏览器同源策略的限制下上述状况不会发生。编程
所以,浏览器同源策略的做用是防止跨站请求伪造。json
浏览器的同源限制是种伤敌一千自损八百的作法,如对于一个大系统来讲有不少域名是正常的,同源限制使得同一系统内的不一样域名下的服务没法互相访问。后端
要突破浏览器跨域访问的限制,本质上有三种方法:跨域
注:浏览器
JSONP、CORS须要目标站点的配合(JSONP须要服务端代码调用回调函数、CORS须要服务端配置容许的origin的白名单),不然没法实现,第一种则不须要;
AJAX已封装支持了JSONP功能,但此时其和传统意义上的AJAX请求是不同的,本质上是不一样东西:ajax的核心是经过XmlHttpRequest获取非本页内容,而jsonp的核心则是动态添加<script>标签来调用服务器提供的js脚本。更多参考:jsonp原理
CORS与JSONP的使用目的相同,可是比JSONP更强大。JSONP只支持GET请求,CORS支持全部类型的HTTP请求。JSONP的优点在于支持老式浏览器,以及能够向不支持CORS的网站请求数据。
思考:上一节中所述危害是以没有同源限制为前提的,现实是浏览器都作了严格的同源限制,故该状况不会发生。然而在有同源限制下,咱们仍可利用法2实现一个盗取用户信息的恶意脚本:
一、脚本干的事为读取当前所在用户站点的cookie等信息,并发送到脚本制做者的站点;
二、发送涉及到跨域,因为是“本身人”,能够选择jsonp解决跨域;
三、弄个恶意连接诱导用户点击,从而将恶意脚本加载到用户站点,因为浏览器加载完script后就好执行,故done。
上述过程其实就是跨站脚本攻击(Cross-Site Scripting,XSS)的一种例子,经过XSS获取到认证信息后就自热而然地能够用认证信息进行CSRF了。
浏览器的同源策略用来确保在浏览器内对后端发起访问的前端是可信赖的前端。除了依靠浏览器源限制外,后端服务还能够根据所收到请求的origin字段来限制白名单(origin字段由浏览器自动加入HTTP header,用户没法经过编程方式如javascript修改;固然,经过中间人攻击仍是能够修改的,此时可用HTTPS或wss防范)。
目前,对于新兴的WebSocket协议(2008年诞生,2011年成为国际标准,目前全部浏览器都已支持),浏览器未作同源限制。所以应用要注意防范CSRF攻击,可借助token或上述的origin等方式防范。