您的位置:首页 > 其它

Web阶段性技术文档(三)

2020-02-03 04:21 411 查看

 

一、Ajax设置请求和接收响应

1、JS设置任意请求

一个http请求分为四个部分

请求行,请求头,回车,请求体

      

设置请求的四个部分(第三部分为回车):

第一部分 request.open('get', '/xxx')

第二部分 request.setRequestHeader('content-type','x-www-form-urlencoded')

第四部分 request.send('a=1&b=2')

 

request.setRequestHeader()方法需要注意的是此方法必须在 open() 方法和 send() 之间调用

XMLHttpRequest.setRequestHeader()

 

另外需要注意的是,如果设置西请求方法为get 并且设置了请求体(第四部分),在谷歌浏览器中看不到请求体,不报错但是不显示

 

示例代码:

myButton.addEventListener("click",(e)=>{

    let request = new XMLHttpRequest();

    request.open('POST','/xxx')//配置request

    //设置第二部分

    request.setRequestHeader("mataotao","123123xxx")

    request.setRequestHeader('content-type','x-www-form-urlencoded')

    request.send("a=1&b=2");//发送请求

    request.onreadystatechange = ()=>{

        if(request.readyState ===4){

            console.log("请求和响应都完毕了");

            if ( request.status>=200&&request.status<=400){

                console.log('说明请求成功');

                let string = request.responseText;

                //把符合json语法的字符串转化为js对应的值

                let object2 = window.JSON.parse(string);

                console.log(object2)

            }else if(request.status>=400){

                console.log("响应失败");

            }} }})

 

查看请求:

 

2、JS获取任意响应

响应的四个部分:

获取四个部分的响应

第一部分 request.status / request.statusText

第二部分 request.getResponseHeader() / request.getAllResponseHeaders()

第四部分 request.responseText

 

myButton.addEventListener("click",(e)=>{

    let request = new XMLHttpRequest();

    request.open('POST','/xxx')//配置request

    //设置第二部分

    request.setRequestHeader("mataotao","123123xxx")

    request.setRequestHeader('content-type','x-www-form-urlencoded')

    request.send("a=1&b=2");//发送请求

 

    request.onreadystatechange = ()=>{

        if(request.readyState ===4){

            console.log("请求和响应都完毕了");

            if ( request.status>=200&&request.status<=400){

                console.log('说明请求成功');

 

                //*核心代码 */

                //第一部分:

                console.log("获取响应第一部分:")

                console.log(request.status)//200

                console.log(request.statusText)//ok

                //第二部分:

                console.log("获取响应第二部分:")

                console.log(request.getResponseHeader('Content-Type'))

                console.log(request.getAllResponseHeaders())

                //第四部分:

                console.log("获取响应第四部分:")

                console.log(request.responseText)

 

                 //*核心代码 */

                let string = request.responseText;

                //把符合json语法的字符串转化为js对应的值

                let object2 = window.JSON.parse(string);

                // console.log(object2)

 

            }else if(request.status>=400){

                console.log("响应失败");

            }

        }

    }

})

 

 

二、自己封装简易jQuery

1、方法一

window.jQuery = ()=>{//假装有一个简易的jQuery,具体封装

    let object1 = {};

    boject1.addClass = function(){};

    boject1.show = function(){};

    return object1;

}

 

window.jQuery.ajax = (method,path,body,successFn,failFn)=>{

    let request = new XMLHttpRequest();

    request.open(method,path)

    request.send(body);

    request.onreadystatechange = ()=>{

        if(request.readyState ===4){

            if ( request.status>=200&&request.status<=400){

               successFn.call(undefined,request.responseText)//执行成功函数

            }else if(request.status>=400){

                failFn.call(undefined,request)//执行失败函数

            }

        }

    }

}

 

window.$ = window.jQuery;

myButton.addEventListener("click",(e)=>{

    //使用ajax

    $.ajax("post",

           "/xxx",

           "username=mtt&password=1",

           function(result){

                console.log('成功了,返回的响应体为:')

                console.log(result);//打印request.responseText

           },

           function(result){

                console.log(result);

                console.log(result.status);//打印失败的状态码

                console.log(result.responseText);//打印失败时返回的响应体

               

           }

)

})

结果:

成功时:

 

 

 

失败时:(假如请求一个不存在的路径,响应状态码是404,但是也有响应体responseText)

例如,访问一个不存在的路径/frank:

myButton.addEventListener("click",(e)=>{

    //使用ajax

    $.ajax("post",

           "/frank",

           "username=mtt&password=1",

           function(result){

                console.log('成功了,返回的响应体为:')

                console.log(result);//打印request.responseText

           },

           function(result){

                console.log(result);

                console.log(result.status);//打印失败的状态码

                console.log(result.responseText);//打印失败时返回的响应体

               

           }

)

})

 

返回状态码404,而且有设置的返回体

 

服务器端的代码为:

else {

    response.statusCode = 404

    response.setHeader('Content-Type', 'text/html;charset=utf-8')

    response.write(`{

      "error":"404error"

    }`)

    response.end()

  }

这种方法的缺点:这个函数必须按照规定的顺序传参

第二,如果没有参数就会出现类似于$.ajax("post",null,successFn,null)的情况,必须传有结构的参数(对象)

 

三、回调

1、什么是回调

在上面的代码中,在ajax函数中传了一个successFN,failFn函数作为参数,但是执行的时候是在别的地方执行的(在request.onreadystatechange里)

 if(request.readyState ===4){

            if ( request.status>=200&&request.status<=400){

                successFn.call(undefined,request.responseText)//执行成功函数

            }else if(request.status>=400){

                failFn.call(undefined,request)//执行失败函数

这两个函数就是回调函数

 

回调(callback):回来执行的意思,自己不call.

把这个函数给别人,自己不执行,让别人执行,就是callback

 

回调:使用方代码不执行,只传一个函数,回来再执行

回调就是传一个函数,自己不执行,传到别的地方让他在那里执行的函数,只要满足这个条件就叫回调而已.他是一个函数,只不过在别的地方执行了

所以看上去没有执行,实际上success了就执行传进去的这个函数

 

Callback 很常见

$button.on('click', function(){})

click后面的 function 就是一个回调,因为「我」没有调用过这个函数,是 jQuery 在用户点击 button 时调用的(当用户点击之后,这个函数才执行,现在我只是传了一个参数,这个参数是一个点击后要执行的函数)。

 

div.addEventListener('click', function(){})

click 后面的 function 也是一个回调,因为「我」没有调用过这个函数,是浏览器在用户点击 button 时调用的。

 

一般来说,只要参数是一个函数,那么这个函数就是回调。

封装的简易jQuery.ajax()中的successFN就是一个回调函数。

 

只有在请求成功并接收到响应的时候才会执行这个success函数,这就是回调.传一个函数作为参数但是不执行,让另一个函数去调用,就是回调函数。

 

2、方法二:传有结构的参数(对象)

let myButton = document.getElementById('myButton');

window.jQuery = ()=>{//假装有一个简易的jQuery

    let object1 = {};

    boject1.addClass = function(){};

    boject1.show = function(){};

    return object1;

}

window.jQuery.ajax = (options)=>{

    //获取传进来的对象的value

    let method = options.method;

    let path = options.path;

    let body = options.body;

    let successFn = options.successFn;

    let failFn = options.failFn;

    let headers = options.headers;

 

    let request = new XMLHttpRequest();

    request.open(method,path);//配置

 

    for (const key in headers) {//遍历header,设置响应头

        let value = headers[key];

        request.setRequestHeader(key,value);

    }

    request.send(body);//发送,并配置响应体

 

    request.onreadystatechange = ()=>{

        if(request.readyState ===4){

            if ( request.status>=200&&request.status<=400){

              successFn.call(undefined,request.responseText);//执行成功函数

            }else if(request.status>=400){

                failFn.call(undefined,request);//执行失败函数

            }

        }

    }

}

window.$ = window.jQuery;

myButton.addEventListener("click",(e)=>{

    //使用ajax

    $.ajax({

        method:"post",

        path:"/xxx",

        body:"username=mtt&password=1",

        headers:{

            "content-type":'application/x-www-form-urlencoded',

            "mataotao":18

        },

        successFn:function(result){//成功函数的回调

            console.log('成功了,返回的响应体为:');

            console.log(result);//打印request.responseTex

        },

        failFn:function(){

            console.log(result);

            console.log(result.status);//打印失败的状态码

            console.log(result.responseText);//打印失败时返回的响应体

        }

    })})

 

结果:

 

3、真正的jQuery.ajax()API如何使用

$.ajax({

  type: "GET",

  url: "/test",

  dataType: "script",

  data:{}

  success:function(){},

});

 

dataType就是setRequestHeader("content-type","application/javascript")

data就是请求的第四部分

 

四、使用Promise封装ajax()

1、$.Ajax()中的promise

如果不使用promise,$.ajax请求的时候成功和失败的回调函数是写在参数里的,他是对象参数的一个值。

$.ajax({

        method:"post",

        url:"/xxx",

        data:"username=mtt&password=1",

        dataType:'json',

        success:()=>{}//成功后的回调函数

        error:()=>{}//失败后的回调函数

    }

    )

如果使用jQuery.axja()发送请求,并使用promise,代码如下:

let myButton = document.getElementById('myButton');

 

function success(responseText){

    console.log("成功")

    console.log(responseText);//responseTex

}

function fail(request){

    console.log("失败")

    console.log(request);

}

myButton.addEventListener("click",(e)=>{

    //使用ajax

    $.ajax({

        method:"post",

        url:"/xxx",

        data:"username=mtt&password=1",

        dataType:'json'//预期服务器返回的数据类型,如果不写,就是响应里设置的

    }

    ).then(success,fail)//$.ajax()返回一个promise

})

成功的结果:

$.ajax()函数会返回一个promise,然后在后面.then(success,fail)时候,如果成功了就会调用第一个参数里的函数即success函数,如果失败了就会调用第二个参数的函数即fail函数.

 

 

 

2、promise的第一个意义

promise的第一个意义:不用记住成功和失败到底是success,还是successFN或者是fail或者是error,不用记住函数名字.只需要知道成功是第一个参数,失败时第二个参数,比如这样写:

//使用ajax

    $.ajax({

        method:"post",

        url:"/xxx",

        data:"username=mtt&password=1",

        dataType:'json'//预期服务器返回的数据类型,如果不写,就是响应里设置的

    }

).then((responseText)=>{console.log(responseText)},()=>{console.log("失败")})//$.ajax()返回一个promise

 

完全不需要写函数名

 

3、promise的第二个意义

如果你需要对一个结果进行多次处理,可以这样写:

$.ajax({

        method:"post",

        url:"/xxx",

        data:"username=mtt&password=1",

        dataType:'json'//预期服务器返回的数据类型,如果不写,就是响应里设置的

    }

    ).then((responseText)=>{

        console.log(responseText)

        return responseText;//如果要对结果进行多次处理,就在这里return,第二次then就会得到这个return的数据

    },()=>{

        console.log("失败")

    }).then(//开始第二次then

        (上一次return的结果)=>{

            console.log("第二次处理")

            console.log(上一次return的结果)

        },

        ()=>{

            //第二次处理失败结果

        }

    )

 

结果:

看到第二个then里的函数吧第一次then里return的结果当做参数,继续处理.

所以promise的好处是如果想再次用两个函数,即再次对结果进行处理,就再then 一下,不需要再次取名字了

then的中文含义:然后

 

以上就是ajax中promise的简单使用,那么如何自己封装一个呢?

PS:ajax()函数参数里的dataType:'json'//预期服务器返回的数据类型,如果不写,就是响应里设置的 即:

ajax方法中的dataType:预期服务器返回的数据类型。如果不指定,jQuery 将自动根据 HTTP 包 MIME 信息来智能判断。

 

4、封装一个类似$.Ajax()中的Promise的简易版本

接下来回到我们自己封装的jQuery.Ajax()代码.我们以此为基础继续来封装promise。原来的封装Ajax()代码核心部分:

window.jQuery.ajax = ({method,path,body,successFn,failFn,headers})=>{//ES6语法

   

    let request = new XMLHttpRequest();

    request.open(method,path);//配置

 

    for (const key in headers) {//遍历header,设置响应头

    let value = headers[key];

        request.setRequestHeader(key,value);

    }

    request.send(body);//发送,并配置响应体

 

    request.onreadystatechange = ()=>{

        if(request.readyState ===4){

            if ( request.status>=200&&request.status<=400){

                successFn.call(undefined,request.responseText);//执行成功函数

            }else if(request.status>=400){

                failFn.call(undefined,request);//执行失败函数

            }

    }

    }

}

 

5、开始封装

封装之后的完整代码:

window.jQuery.ajax = ({method,path,body,headers})=>{//ES6语法

//进行Promise封装

return new Promise((resolve,reject)=>{//这句话是套路,记住

let request = new XMLHttpRequest(); request.open(method,path);//配置

for (const key in headers) {//遍历header,设置响应头

let value = headers[key];

request.setRequestHeader(key,value);

}

request.send(body);//发送,并配置响应体

request.onreadystatechange = ()=>{

if(request.readyState ===4){

if ( request.status>=200&&request.status<=400){ resolve.call(undefined,request.responseText);//执行成功函数

}else if(request.status>=400){

 reject.call(undefined,request);//执行失败函数

} } } }) }

 

return 一个new Promise().

第一个要记住的:这个Promise必须接收一个函数,函数里面就是要做的事情(即发送请求,Ajax请求),一般来说,把所有东西放在里面,第一句就是return.然后要做的事情放在里面.

第二个要记住的:Promise接收的这个函数有两个参数,一个叫做resolve.一个叫reject

前两个要记住的写出来就是

return new Promise((resolve, reject) => { //要做的事 });

 

第三个要记住的:如果成功了就调一下resolve(),如果失败了就调用reject(),所以Ajax()参数中不需要successFn和failFn了

并且将成功行和失败行对应的代码分别改为

resolve.call(undefined,request.responseText);

//执行成功函数和

reject.call(undefined,request);//执行失败函数

上面是固定的套路,封装完毕.只分别修改了这几行代码:

 

  1. 如何调用

 

myButton.addEventListener("click",(e)=>{

    //使用ajax

    $.ajax({

        method:"post",

        path:"/xxx",

        body:"username=mtt&password=1",

        headers:{

            "content-type":'application/x-www-form-urlencoded',

            "mataotao":18

        }

    }).then(

        (responseText)=>{console.log(responseText);},//成功就调用这个函数

        (request)=>{console.log(request);}//失败就调用这个函数

    )

})

 

在ajax()函数后接上.then(),成功就调用then()函数第一个参数里的函数,失败就调用then()函数第二个参数里的函数

简单的Promise原理:

自己封装后的Ajax()返回一个new出来的 Promise对象,一个Promise实例,这个Promise实例有一个then属性,他是一个函数,所以可以调用then().而且then也会返回一个Promise对象.

Promise接收一个函数,这个函数就是你要做的事情

所以Promise本质上只是规定一种形式

 

 

五、Promise总结

Promise用法:

function xxx(){

    return new Promise((f1, f2) => {

        doSomething()

        setTimeout(()=>{

            // 成功就调用 f1,失败就调用 f2

        },3000)

    })

}

xxx().then(success, fail)

// 链式操作

xxx().then(success, fail).then(success, fail)

 

六、参考资料

1、AJAX学习笔记(四、请求与响应)

https://blog.csdn.net/sinat_40770656/article/details/95457750

2、jQuery版AJAX简易封装代码

https://www.geek-share.com/detail/2684832895.html

3、回调函数

https://baike.baidu.com/item/回调函数/7545973?fr=aladdin

4、Promise - 廖雪峰的官方网站

https://www.liaoxuefeng.com/wiki/1022910821149312/1023024413276544

 

  • 点赞
  • 收藏
  • 分享
  • 文章举报
xiehuiru 发布了17 篇原创文章 · 获赞 1 · 访问量 667 私信 关注
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: