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

1. what

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

 浏览器出于安全考虑会限制跨域访问(即同源策略)。在该限制下,除非两个网页是来自于同一‘源头’, 否则不允许一个网页的JavaScript访问另外一个网页的内容,像Cookie,DOM,LocalStorage均禁止访问;但对具有src属性的标签(如script、img、iframe等)不做跨域限制。

 

2. why

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

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

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

关于浏览器跨域访问(同源策略)_第1张图片

 

上述过程就是跨站请求伪造(Cross-site request forgery,CSRF)的一种例子,所幸在有浏览器同源策略的限制下上述情况不会发生。

因此,浏览器同源策略的作用是防止跨站请求伪造。

3. 如何克服同源限制

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

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

  1. 只需要让不同地址对浏览器来说是同源的即可。如可以通过反向代理把需要互相访问的地址放到反向代理后,这样对浏览器来说就是同源的了。参考:通过Nginx反向代理实现跨域访问-cnblogs
  2. 绕过:JSONP。浏览器对具有src属性的标签(如script、img、iframe等)不做跨域限制,利用这些来实现跨域(即 jsonp)。原理:在页面append一个script标签,标签地址为被跨域访问站点地址,并在地址上加入自定义的回调函数名参数,如?callback=myCallbackFunction,这里的"callback"可以为其他,应事先商定好;被跨域站点的响应逻辑:若未检查到"callback"参数则直接返回data,否则将data作为回调函数名的参数一起返回,即 myCallbackFunction( data );浏览器script加载完后会执行myCallbackFunction函数,因此可以在myCallbackFunction里对请求返回的data进行处理。参考:跨域与跨域访问-csdn
  3. 协议支持:W3C标准中的跨域资源共享(Cross-Origin Resource Sharing,CORS)。它允许浏览器向跨源服务器发出XMLHttpRequest请求,从而克服了AJAX只能同源使用的限制(在实现上借助了 Access-Control-Allow-Origin 等header来与服务端协商)。在前后端分离的场景下两者独立部署,常借助此来实现前端跨域访问后端。内部原理详见:跨域资源共享-阮一峰

注:

JSONP、CORS需要目标站点的配合(JSONP需要服务端代码调用回调函数、CORS需要服务端配置允许的origin的白名单),否则无法实现,第一种则不需要;

AJAX已封装支持了JSONP功能,但此时其和传统意义上的AJAX请求是不一样的,本质上是不同东西:ajax的核心是通过XmlHttpRequest获取非本页内容,而jsonp的核心则是动态添加

你可能感兴趣的:(关于浏览器跨域访问(同源策略))