关于浏览器跨域访问(同源策略)

1. what

跨域是指从一个域名的网页去访问另一个域名的网页。一个完整URL地址通常由 协议+主机+端口+路径[+hash或search] 组成,其中hash和search是可选项、协议未列出则默认为http、port未列出则默认为80值。因此严格来说,两个网页地址的协议(http/https)、主机、端口三者任何一个不同就可以认为是跨域访问,即使两个地址是不同子域名也是跨域,如app.baidu.com与baidu.com。

2. why

浏览器出于安全考虑会限制跨域访问(即同源策略),若不加限制则在一个站点上访问后本地存储的cookie等信息在访问第二个站点时就可能泄露了。(从这可见,跨域限制只是在通过浏览器访问时才存在,因此通过HTTP客户端等访问显然没有跨域限制问题)

没有同源限制时的危害示例

在浏览器上先登录股票网站www.stock.com,得到了cookie,以后再访问stock时浏览器会自动带上cookie;接着访问恶意网站www.beautify.com,假定该网站页面中包含一个恶意js脚本,其行为是去访问stock并把得到的信息发到beautify网站,由于访问stock时浏览器会自动带上cookie故恶意脚本可以成功窃取到数据。示意图如下:

 

所幸浏览器有跨域访问限制,故上述情况不会发生。

3. how

浏览器的同源限制是种伤敌一千自损八百的做法,如对于一个大系统来说有很多域名是正常的,同源限制使得同一系统内的不同域名下的服务无法互相访问。

要突破浏览器跨域访问的限制,本质上有两种方法:

  1. 只需要让不同地址对浏览器来说是同源的即可。如可以通过反向代理把需要互相访问的地址放到反向代理后,这样对浏览器来说就是同源的了。参考:通过Nginx反向代理实现跨域访问-cnblogs
  2. 浏览器对具有src属性的标签(如script、img、iframe等)不做跨域限制,利用这些来实现跨域(即 jsonp)。原理:在页面append一个script标签,标签地址为被跨域访问站点地址,并在地址上加入自定义的回调函数名参数,如?callback=myCallbackFunction,这里的"callback"可以为其他,应事先商定好;被跨域站点的响应逻辑:若未检查到"callback"参数则直接返回data,否则将data作为回调函数名的参数一起返回,即 myCallbackFunction( data );浏览器script加载完后会执行myCallbackFunction函数,因此可以在myCallbackFunction里对请求返回的data进行处理。参考:跨域与跨域访问-csdn

第二种方法JSONP需要目标站点的配合,否则无法实现,第一种则不需要;

AJAX已经封装支持了JSONP功能,但此时其和传统意义上的AJAX请求是不一样的,本质上是不同东西:ajax的核心是通过XmlHttpRequest获取非本页内容,而jsonp的核心则是动态添加<script>标签来调用服务器提供的js脚本。更多参考:jsonp原理

 

思考:上一节中所述危害是以没有同源限制为前提的,现实是浏览器都做了严格的同源限制,故该情况不会发生。然而在有同源限制下,我们仍可利用法2实现一个盗取用户信息的恶意脚本:1、脚本干的事为读取当前所在用户站点的cookie等信息,并发送到脚本制作者的站点;2、发送涉及到跨域,由于是“自己人”,可以选择jsonp解决跨域;3、弄个恶意链接诱导用户点击,从而将恶意脚本加载到用户站点,由于浏览器加载完script后就好执行,故done。

猜你喜欢

转载自www.cnblogs.com/z-sm/p/10242543.html