通信—跨域资源共享

跨域

由于浏览器同源策略,凡是发送请求url的协议、域名、端口三者之间任意一与当前页面地址不同即为跨域。

浏览器的同源策略会导致跨域,这里同源策略又分为以下两种

  1. DOM同源策略:禁止对不同源页面DOM进行操作。这里主要场景是iframe跨域的情况,不同域名的iframe是限制互相访问的。
  2. XmlHttpRequest同源策略:禁止使用XHR对象向不同源的服务器地址发起HTTP请求。

 

为什么要有跨域限制

了解完跨域之后,想必大家都会有这么一个思考,为什么要有跨域的限制,浏览器这么做是出于何种原因呢。其实仔细想一想就会明白,跨域限制主要是为了安全考虑。 

AJAX同源策略主要用来防止CSRF攻击。如果没有AJAX同源策略,相当危险,我们发起的每一次HTTP请求都会带上请求地址对应的cookie,那么可以做如下攻击:

  1. 用户登录了自己的银行页面 向用户的cookie中添加用户标识。
  2. 用户浏览了恶意页面 。执行了页面中的恶意AJAX请求代码。
  3. 发起AJAX HTTP请求,请求会默认把对应cookie也同时发送过去。
  4. 银行页面从发送的cookie中提取用户标识,验证用户无误,response中返回请求数据。此时数据就泄露了。
  5. 而且由于Ajax在后台执行,用户无法感知这一过程。

 

DOM同源策略也一样,如果iframe之间可以跨域访问,可以这样攻击:

  1. 做一个假网站,里面用iframe嵌套一个银行网站
  2. 把iframe宽高啥的调整到页面全部,这样用户进来除了域名,别的部分和银行的网站没有任何差别。
  3. 这时如果用户输入账号密码,我们的主网站可以跨域访问到的dom节点,就可以拿到用户的输入了,那么就完成了一次攻击。

所以说有了跨域跨域限制之后,我们才能更安全的上网了。

 

跨域请求方式JSONP和CORS

JSONP

这种方式主要是通过动态插入一个script标签。浏览器对script的资源引用没有同源限制,同时资源加载到页面后会立即执行(没有阻塞的情况下)。

1 <script>
2       var _script = document.createElement('script');
3       _script.type = "text/javascript";
4       _script.src = "http://localhost:8888/jsonp?callback=f";
5       document.head.appendChild(_script);
6     </script>

  实际项目中JSONP通常用来获取json格式数据,这时前后端通常约定一个参数callback,该参数的值,就是处理返回数据的函数名称。

<!doctype html>
<html>
  <head>
    <meta charset="utf-8">
    <meta name="viewport" content="initial-scale=1, maximum-scale=1,user-scalable=no">
    <title>jsonp_test</title>

    <script>
      var f = function(data){
        alert(data.name);
      }
      /*var xhr = new XMLHttpRequest();
      xhr.onload = function(){
        alert(xhr.responseText);
      };
      xhr.open('POST', 'http://localhost:8888/cors', true);
      xhr.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
      xhr.send("f=json");*/
    </script>
    
    <script>
      var _script = document.createElement('script');
      _script.type = "text/javascript";
      _script.src = "http://localhost:8888/jsonp?callback=f";
      document.head.appendChild(_script);
    </script>
  </head>
var query = _url.query;
        console.log(query);
        var params = qs.parse(query);
        console.log(params);
        var f = "";
    
        f = params.callback;
    
        res.writeHead(200, {"Content-Type": "text/javascript"});
        res.write(f + "({name:'hello world'})");
        res.end();

  

  缺点:

  1、这种方式无法发送post请求

  2、另外要确定jsonp的请求是否失败并不容易,大多数框架的实现都是结合超时时间来判定。

 

CORS

请参考阮一峰老师总结的文章:跨域资源共享 CORS 详解

 

CORS与JSONP区别

CORS与JSONP的使用目的相同,但是比JSONP更强大。

JSONP只支持GET请求,CORS支持所有类型的HTTP请求。JSONP的优势在于支持老式浏览器,以及可以向不支持CORS的网站请求数据。

 

 

 

 

参考:

探讨跨域请求资源的几种方式

跨域资源共享 CORS 详解

 

posted @ 2018-09-12 15:04  大象踢足球  阅读(259)  评论(0编辑  收藏  举报