浏览器同源策略和跨域的实现方法

目录

同源策略

跨域

跨域的实现方法

1、降域 document.domain

2、JSONP跨域

3、CORS


同源策略

同源策略(Same origin policy)是一种约定,它是浏览器最核心也最基本的安全功能,如果缺少了同源策略,则浏览器的正常功能可能都会受到影响。可以说Web是构建在同源策略基础之上的,浏览器只是针对同源策略的一种实现。
所谓同源是指域名,协议,端口相同。
当一个浏览器的两个tab页中分别打开百度和谷歌的页面时,当浏览器的百度tab页执行一个脚本的时候会检查这个脚本是属于哪个页面的,即检查是否同源,只有和百度同源的脚本才会被执行。 如果非同源,那么在请求数据时,浏览器会在控制台中报一个异常,提示拒绝访问。不同源的客户端脚本在没有明确授权的情况下,不能读写对方资源。所以google.com下的js脚本采用ajax读取baidu.com里面的文件数据是会报错的。

如何判断是否是同源,可以查看该表

不受同源策略限制的:

  • 页面中的链接,重定向以及表单提交是不会受到同源策略限制的。
  • 跨域资源的引入是可以的。但是js不能读写加载的内容。如嵌入到页面中的<script src="..."></script>,<img>,<link>,<iframe>等 

跨域

跨域:受前面所讲的浏览器同源策略的影响,不是同源的脚本不能操作其他源下面的对象。想要操作另一个源下的对象是就需要跨域。

跨域的实现方法

1、降域 document.domain


同源策略认为域和子域属于不同的域,如:
child1.a.com 与 a.com,
child1.a.com 与 child2.a.com,
abc.child1.a.com 与 child1.a.com 
两两不同源,但是可以通过设置 document.domain='a.com',浏览器就会认为它们都是同一个源。想要实现以上任意两个页面之间的通信,两个页面必须都设置documen.domain='a.com'。
此方式的特点:

  • 只能在父域名与子域名之间使用,且将 xxx.child1.a.com域名设置为a.com后,不能再设置成child1.a.com
  • 存在安全性问题,当一个站点被攻击后,另一个站点会引起安全漏洞
  • 这种方法只适用于 Cookie 和 iframe 窗口

2、JSONP跨域


注:JSONP和JSON并没有什么关系!
JSONP的原理:

举例:如果 a.com/abc.html 想得到 b.com/main.js 中的数据,可以在a.com的abc.html里创建一个回调函数xxx,动态添加<script>元素,向服务器发送请求,请求地址后面加上查询字符串,通过callback参数指定回调函数的名字。请求地址为http://b.com/main.js?callback=xxx。然后在main.js中调用这个回调函数xxx,并且以JSON数据形式作为参数传递,完成回调。我们来看看代码:

a.com/abc.html的代码

 function addScriptTag(src) { 
   var script = document.createElement('script'); 
   script.setAttribute("type","text/javascript"); 
   script.src = src; 
   document.body.appendChild(script);
 }
 
 //window.onload是为了让页面加载完成后再执行
 window.onload = function () {            
   addScriptTag('http://b.com/main.js?callback=foo');
 }
 function foo(data) { 
   console.log(data.name+"欢迎您");
 }

b.com/main.js 的代码

foo( { name:"hl" } )

 采用jsonp跨域也存在问题:

  • 使用这种方法,只要是个网站都可以拿到b.com里的数据,存在安全性问题。需要网站双方商议基础token的身份验证
  • 只能是GET,不能POST
  • 可能被注入恶意代码,篡改页面内容,可以采用字符串过滤来规避此问题

3、CORS


CORS是一个W3C标准,全称是"跨域资源共享"(Cross-origin resource sharing)。
它允许浏览器向跨源服务器,发出XMLHttpRequest请求,从而克服了AJAX只能同源使用的限制。
刚才的例子中,用CORS实现跨域。
在b.com里面添加响应头声明允许a.com的访问,代码

Access-Control-Allow-Origin: http://a.com

然后a.com就可以用ajax获取b.com里的数据了。
注意:此方法IE8以下完全不支持,IE8-10部分支持。详见:caniuse-CORS
 

还有一些其他的方法可以实现跨域请求数据:

  • HTML5的postMessage方法
  • window.name
  • location.hash

猜你喜欢

转载自blog.csdn.net/qq_36119192/article/details/82931250