AJAX(下)

113 阅读2分钟
  1. JS可以设置任意请求header吗?

    可以
    var request = new XMLHttpRequest();
    第一部分:request.open('GET','http://xxx.com')
    第二部分:request.setHeader('content-type','x-www-form-urlencoded')
    第四部分: request.send('a=1&b=2')
     
    
  2. JS可以获取任意相应么

    可以,
    第一部分: request.status//200  request.statusText //ok
    第二部分: request.getResponseHeader()
               或者request.getAllResponseHeaders()
    第四部分   request.responseText
    
    
  3. Q:浏览器是一开始就知道是 200还是 400,还是在下载完毕之后才知道的呢?

var request = new XMLHttpRequest();
request.open('GET','http://xxx.com');
request.send();
request.onreadystatechange = () => {
    if (request.readyState === 4) {
        //4的时候表示请求与响应都已经完成
        if (request.status >=200 && request.status < 300) {
            let string = request.responseText;(后端返回的都是string)
            let obj = JSON.parse(string)(将string转变成json,更利于前端处理数据)
        }
    }
}

浏览器是先接收到200 或者 300 或者400 也就是状态码之后,才开始接收返回的数据的。
但是我们是等到request.readyState === 4时,才去读取返回的内容的,
因为state为4的时候,代表数据全部下载完成了。

上面的ajax请求是先判断state是否为4再判断 status是否为200, 
这样做的理由是 只有等state到了4之后,我们才能获取完整的返回的内容
,这个时候再去判断status是成功还是失败,从而开始处理返回的内容

Promise

return new Promise(function(resolve,reject){
    
})
jquery的ajax用法
$.ajax({
    url:'xxx',
    method:'get',
    success:function() {},
    error:function() {}
})

jquery的ajax的promise写法
$.ajax({
    url:'xxx',
    method:'get'
}).then(
    ()=>{
       console.log('success') 
    },
    ()=>{
       console.log('fail') 
    }
)
不需要再写success,error了 不需要再给回调方法取名字了
$.ajax({
    url:'xxx',
    method:'get'
}).then(()=>{console.log('success'),return 'success' },()=>{console.log('fail'),return 'error'})
.then((data)=>{console.log(data) },(data)=>{console.log(data)})
如果还要再回调,可以在then的后面再写then,
后面一个then可以接收到前面一个then return出来的数据,
如果前面是走的是success ,那么后面打印出来的就是'success',
如果前面走的是fail,那么后面打印出来的就是'fail'.
所以,then的好处就是可以基于同一个数据做二次处理

注意:jquery的ajax的返回值是一个对象,为什么呢?
因为jquery发现你的Response Headers中的content-type写的是text/json,
所以,就自动帮你JSON.parse('string')了,不需要我们再做转化工作了。
如何自己封装jquery ajax的promise用法?

1.首先自己封装一个jquery的ajax

window.jquery = function(nodeOrSelector) {
    let nodes ={};
    nodes.addClass = function() {};
    nodes.html=function() {};
    return nodes;
}
window.$ = window.jquery;
$.ajax = function({url,method,headers,params,successFn,failFn}) {
    let request = new XMLHttpRequest();
    request.open(method,url);
    for (let key in headers) {
        let value = headers[key];
        request.setRequestHeaders(key,value)
    }
    request.onreadystatechange = function() {
        if (request.readyState === 4) {
            if (request.status >=200 && request.status < 300) {
                successFn.call(undefined,request.responseText)
            } else if(request.status >= 400){
                failFn.call(undefined,request.responseText)
            }
        }
    }
    request.send(params)
}

以上是自己封装的ajax,然而这个的返回值是undefined.

如果我们要封装成promise的用法的话,我们就需要返回一个promise对象.

Promise其实就是window.Promise, Promise就是window下面的一个属性。
可以在控制在下输入window然后回车 就可以找到Promise了。
Promise接收一个函数,
return new Promise(function(){
    
}),这个函数其实就是回调,这个函数里面写的就是你要做的事情,我们现在要做的是什么呢?就是发请求。
 
那么上面的代码就改写为:
$.ajax = function({url,method,headers,params}) {
    return new Promise(function( resolve, reject ) {
        let request = new XMLHttpRequest();
        request.open(method,url);
        for (let key in headers) {
            let value = headers[key];
            request.setRequestHeaders(key,value)
        }
        request.onreadystatechange = function() {
            if (request.readyState === 4) {
                if (request.status >=200 && request.status < 300) {
                    resolve.call(undefined,request.responseText)
                    //这里改写成resolve
                } else if(request.status >= 400){
                    reject.call(undefined,request.responseText)
                    //这里改写成reject
                }
            }
        }
        request.send(params)
    })
}
目前ajax的返回值就是一个Promise对象,这个promise接收的是一个函数,
这个函数就是你要做的事情。
Promise的主要实现:
Promise等于一个函数,使用的时候要传一个函数,会return 一个then出来
window.Promise = function(fn){
    //.....
    return {
        then: function(){}
    }
}

那么我们在使用以上的ajax的时候,就可以这样使用
btn.on('click',function() {
    $.ajax({
        url:'xxx',
        method:'GET',
        headers:{
        'contnt-type':'application/x-www-form-urlencoded',
        'frank':18
        }
    }).then(()=>{console.log('1')},()=>{console.log('2')})
})

then返回的也是promise对象,所以就可以继续then