首页 > 技术文章 > 跨域与闭包

BR-Tao 2019-08-14 19:06 原文

跨域

当违背同源策略时就会发生跨域问题

常见的解决跨域问题的方法有jsonp , cors  , 服务器代理。。。

cors

cors是一种标准,现已支持绝大多数的浏览器,当浏览器检测到你发送的是跨域请求时会进行一个简单的处理(给请求头加上 Origin (协议 + 域名 + 端口))

cors服务端会将这个字段作为跨域标志,接受到后会对origin进行判断是否为允许源,验证通过服务端会给请求头加上access-Control-Allow-Origin、Access-Control-Allow-Credentials等字段。

cors里面有一个简单请求与非简单请求的概念,简单请求的条件如下:

 

(1) 请求方法是以下三种方法之一:

     HEAD GET POST

 

2)HTTP的头信息不超出以下几种字段:

     Accept Accept-Language

    Content-Language Last-Event-ID

    Content-Type: application/x-www-form-urlencoded、

    multipart/form-data、text/plain

简单请求如上所说正常进行,非简单请求会在发送前先发送一个options类型的预检请求,验证通过之后才会执行真正的请求;

 

 关于jsonp的原理分析

 在前端里使用jsonp需要进行如下设置
    // 动态创建script标签发出去的请求是异步请求
    // 服务器响应的内容是【函数调用】

// 创建script标签
    var script = document.createElement('script');
    // 设置回调函数(因为是异步操作,所以该回调函数可以放在任何位置)
    // 这里的getData函数实际是有服务器的响应内容(内容就是js代码-函数调用 
    // getData(data)调用)
    function getData(data){
        //数据请求回来会被触发的函数
        console.log(data);
    }
    // 设置script 的src属性,设置请求地址
    script.src = 'http://localhost:3000?callback=getData'; //假设get请求,url里保存地址
    // 让script生效
    document.body.appendChild(script);

        

关于callback函数可以自定义,回调函数的命名需与后端保持一致

// 创建script标签
    var script = document.createElement('script');
    // 设置回调函数
    function hello(data){
        //数据请求回来会被触发的函数
        console.log(data);
    }
    // 设置script 的src属性,设置请求地址
    //script.src = 'http://localhost:3000?callback=getData'; //假设get请求,url里保存地址
    script.src = 'http://localhost:3000?[与后端约定的命名]hello=getData';
    // 让script生效
    document.body.appendChild(script);

    // hello就是回调函数
    // 这就是jsonp的本质:动态创建script标签,然后通过它src属性发送跨域请求,然后服务器响应数据格式为【函数调用(hello(实参))】,所以在发送请求前必须先声明一个函数,
   // 并且函数的名字与参数中传递的名字要一致,
   // 这里声明的函数是由服务器响应的内容(实际就是一段js代码-函数调用)来调用

 

闭包

什么是闭包?

1,密闭的容器,类似于set,map容器,存储数据的容器

2,闭包是一个对象,存放数据的格式:key:value

形成的条件

  1.函数嵌套

  2.内部函数引用外部函数的局部变量

闭包的优点:

  延长外部函数局部变量的生命周期

闭包的缺点:

  容易造成内存的泄露

注意点:

  1,合理使用闭包

  2,用完闭包要及时清除(销毁)

简单闭包面试题:

(1)说出打印结果

function fun (){
        var count = 1;
        return function(){
            count++;
            console.log(count);
        }
    }
    var fun2 = fun();
    fun2();    //2
    fun2();    //3

(2)说出打印情况

function fun(n,o){
        console.log(o);
        return{
            fun:function(m){
                return fun(m,n)
            }
        }
    }
    var a = fun(0) 
    a.fun(1) 
    a.fun(2)
    a.fun(3)  //undefined,0,0,0

    var b = fun(0).fun(1).fun(2).fun(3)    //undefined,0,1,2,3

    var c = fun(0).fun(1)
    c.fun(2)
    c.fun(3)     //undefined,0,1,1

 

推荐阅读