美文网首页
同源策略、跨域

同源策略、跨域

作者: 黄露hl | 来源:发表于2017-01-06 15:57 被阅读0次

    一、同源策略

    1、先来说说什么是源

    对于以下的这段URL

    http://user:pass@www.company.com:80/dir/index.html?uid=1#ch1
    
    • http:// 协议名
    • user:pass 登录信息
      -www.company.com 域名(或ip地址、服务器地址)
      -80 端口号,http协议默认端口号为80端口,默认情况下没有显示,https默认端口号443,ftp默认21
    • /dir/index.html 带层次的文件路径
    • uid=1 查询字符串
    • #ch1片段标识符(hash)
      源(origin)就是协议、域名和端口号。
      以上url中的源就是:http://www.company.com:80
      若地址里面的协议、域名和端口号均相同则属于同源。

    以下是相对于 http://www.a.com/test/index.html 的同源检测

    2.什么是同源策略?

    同源策略是浏览器的一个安全功能,不同源的客户端脚本在没有明确授权的情况下,不能读写对方资源。所以a.com下的js脚本采用ajax读取b.com里面的文件数据是会报错的。

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

    二、跨域

    1、什么是跨域

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

    2、跨域的实现形式

    • 降域 document.domain

    同源策略认为域和子域属于不同的域,如:

       child1.a.com 与 a.com,
       child1.a.com 与 child2.a.com,
       xxx.child1.a.com 与 child1.a.com
    

    两两不同源,可以通过设置 document.damain='a.com',浏览器就会认为它们都是同一个源。想要实现以上任意两个页面之间的通信,两个页面必须都设置documen.damain='a.com'
    此方式的特点:

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

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

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

    这样便实现了跨域的参数传递。
    采用jsonp跨域也存在问题:

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

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

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

    然后a.com就可以用ajax获取b.com里的数据了。
    注意:此方法IE8以下完全不支持,IE8-10部分支持。详见caniuse-CORS
    详细内容请参考:跨域资源共享 CORS 详解

    • 其它方法

    1. HTML5的postMessage方法
    2. window.name
    3. location.hash
      同源策略以及跨域演示

    相关文章

      网友评论

          本文标题:同源策略、跨域

          本文链接:https://www.haomeiwen.com/subject/rnrzvttx.html