美文网首页
同源策略,跨域请求处理

同源策略,跨域请求处理

作者: 一刀一个小黄鱼 | 来源:发表于2017-08-11 00:20 被阅读82次

    跨域访问 - 跨域请求

    同源策略

    适用于浏览器的一种资源访问策略;

    同源策略(Same origin policy)是一种约定,它是浏览器最核心也最基本的安全功能,如果缺少了同源策略,则浏览器的正常功能可能都会受到影响。可以说Web是构建在同源策略基础之上的,浏览器只是针对同源策略的一种实现。

    浏览器为什么使用同源策略

    同源策略,它是由Netscape提出的一个著名的安全策略。现在所有支持 JavaScript 的浏览器都会使用这个策略。所谓同源是指,域名/IP/主机,协议,端口相同。在浏览器的js中,通过代码(脚本)去访问网络资源的时候会应用该策略

    假设在a页面的地址是(http://www.baidu.com/a.html),

    那么a页面所在的源信息是:协议:http,域名:baidu.com,端口:80

    那么在这个页面中通过js去访问另外一个资源:(http://www.baidu.com/b.html)。

    那么这个时候会使用同源策略进行检测,上面两个页面的协议域名端口是相同的,那么这时候一个同源请求,如果访问的是:(http://www.qq.com/b.html),那么很明显这个时候就是非同源请求,这个时候,请求会受到一定的限制。

    http://www.baidu.com/a.html 为例,以下都是非同源的:

    AJAX请求

    我们使用ajax去请求资源的时候,就被使用同源策略进行检测,同源策略是适用于浏览器的,也就是说如果我们发送了一个跨域的请求,服务器是能接收到并能处理和返回的,但是浏览器在接收到返回数据以后,会比较他们的域是否相同,如果不相同,拒绝接收和处理!

    解决办法

    Access-Control-Allow-Origin

    当浏览器接收到非同源数据的时候,会首先去头信息看Access-Control-Allow-Origin字段里面的值,如果当前域在Access-Control-Allow-Origin里面有包含,则忽略同源策略

    例如我们有给服务器分别为localhost:7777localhost:8888

    当我们在端口8888情况下访问7777的数据时,因为同源策略检测,ajax请求就会直接报错,这时我们需要在被请求也就是8888的后端里设置头信息res.setHeader('Access-Control-Allow-Origin',"localhost:7777"),

    感觉类似白名单一样,如果想所有不同源的端口都访问可以把里面的值改为通配符(*

    后端代理

    后端之间互相访问请求不同源的是不会有同源策略,因为同源策略是基于浏览器来产生的,所以我们可以让自己的服务器后端去访问请求跨域的地址,然后把结果再传给我们,这样就类型一种代理的行为

    //nodejs中axios插件 就集成了服务端去发送请求方法
    app.get('/data', (req, res) => {
    
        /*
        * 通过服务端去发送请求
        * */
        axios.get('http://localhost:8888/data').then( response => {
            //console.log(response.data);
            res.send(response.data);
        } );
    });
    
    //然后ajax在去接收responseText
    var xhr = new XMLHttpRequest();
    
    xhr.open('get', 'http://localhost:8888/data', true);
    
    xhr.onload = function() {
      console.log(this.responseText);
    };
    
    xhr.send();
    
    jsonp

    为了解决同一个接口的调用不同的函数,实现不同的逻辑,那么后端输出的函数名不再固定,而是由前端通过get方式传入一个指定的参数,比如callback,后端根据callback传入的值,输出不同的函数调用名

    弊端:只能通过get方式

    注意:一个api接口是否能够通过jsonp的方式去使用,还要看该接口输出的数据格式,知否能够被script标签加载后被js所执行

    具体方法:通过创建一个script标签,地址指向第三方的API网址,例如被请求方的数据是:

    app.get('/list', (req, res) => {
    
        let callback = req.query.callback || 'fn';
        let type = req.query.type || 'teachers';
    
        let data = {
            teachers: ['Leo','Motao', 'zMouse'],
            students: ['张三','李四', '王五', '赵六', '田七']
        };
    
        res.send(callback + '('+ JSON.stringify(data[type]) +')');
    });
    

    我们通过创建一个script标签,就不会收到同源策略的影响,其中可以通过一个callback函数来接受数据,可以是一个约定的函数名,或者通过地址来传递,这样我们前台在拿数据就可以通过函数名来拿到手

    document.onclick = function() {
      var scriptElement = document.createElement('script');
      scriptElement.src = 'http://localhost:7777/list?callback=fn2&type=students';
      //需要什么信息就传入什么约定好的名字
      document.body.appendChild(scriptElement);
    };
    function fn(data) { //地址中传入的callback名
      var html = '';
      data.forEach( item => {
        html += '<li>'+ item +'</li>';
      } );
      uls[0].innerHTML = html;
    }
    

    相关文章

      网友评论

          本文标题:同源策略,跨域请求处理

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