美文网首页
如何使用 fetch ,加请求头, ajax 和 fetch 和

如何使用 fetch ,加请求头, ajax 和 fetch 和

作者: WEB_Jorie | 来源:发表于2018-07-06 13:51 被阅读0次

    ----欢迎查看我的博客----

    什么是fetch

      我们之前,过度过来都在用ajax,那么什么是 Fetch ,Fetch 是新的游览器对象, 等同于 XMLHttpRequest对象 。它提供了许多与 XMLHttpRequest 相同的功能,但被设计成更具可扩展性和高效性。

    image

    ajax

      废话不多说我们来看一下传统的ajax。

    var xhr;
    if (window.XMLHttpRequest) {
       xhr = new XMLHttpRequest();
    } else if (window.ActiveXObject) { // IE
       try {
         xhr = new ActiveXObject('Msxml2.XMLHTTP');
       } catch (e) {
         try {
           xhr = new ActiveXObject('Microsoft.XMLHTTP');
         } catch (e) {}
       }
    }
    if (xhr) {
       xhr.onreadystatechange = () =>{
           if (xhr.readyState === 4) {
              if (xhr.status === 200) {
                 console.log(xhr.responseText); //返回值传callback
              } else {
                    //failcallback
                 console.log('There was a problem with the request.');
              }
           } else {
              console.log('still not ready...');
           }
        };
       xhr.open('POST', 'https://www.baidu.com', true);
       // 设置 Content-Type 为 application/x-www-form-urlencoded
       // 以表单的形式传递数据
       xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
       xhr.send('username=admin&password=root');
    }
    
    

      好我们来做层封装,让他变成我们 jQuery 的 ajax post
    如这种形式:

    $.ajax({
        method: 'POST', //请求方式
        url: '/api', //url
        data: { username: 'admin', password: 'root' }, //值
        success:function(data){ //成功回掉
            console.log(data)
        },
        error:function(err){
            console.log(err)
        }
    })
    

    好的封装开始:

    const $ = {};
    $.ajax = (obj)=>{
        var xhr;
        if (window.XMLHttpRequest) {
           xhr = new XMLHttpRequest();
        } else if (window.ActiveXObject) { // IE
           try {
             xhr = new ActiveXObject('Msxml2.XMLHTTP');
           } catch (e) {
             try {
               xhr = new ActiveXObject('Microsoft.XMLHTTP');
             } catch (e) {}
           }
        }
        if (xhr) {
           xhr.onreadystatechange = () =>{
               if (xhr.readyState === 4) {
                  if (xhr.status === 200) {
                     obj.success(xhr.responseText); //返回值传callback
                  } else {
                        //failcallback
                     obj.error('There was a problem with the request.');
                  }
               } else {
                  console.log('still not ready...');
               }
            };
           xhr.open(obj.method, obj.url, true);
           // 设置 Content-Type 为 application/x-www-form-urlencoded
           // 以表单的形式传递数据
           xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
           xhr.send(util(obj.data));//处理body数据
        }
        
        //处理数据
        const util = (obj)=>{
            var str = ''
            for (key in obj){
                str += key +'='+obj[key]+'&'
    
            }
            return str.substring(0,str.length-1)
        }
        
    }
    

      ok,咱们已经封装完毕,可以使用了,可是你会发现,这种书写方式很混乱,body,hearder乱七八糟,还有回掉地狱的问题。好的fetch出来了。

    fetch的出现

      我们说了,一种东西的诞生有它的道理,他首先解决了回掉地狱的问题因为返回一个 promise 对象 ,对 promise 对象不是很熟悉的同学可以看这篇文章: 你就需要这篇文章,带你搞懂实战的 Promise 对象。同样既然是 promise 对象我们就可以使用 es7 的 async / await 戳这里。好了废话不多说我们看看最基础的 fetch 怎么写吧 。

    fetch(url, options).then(function(response) {
      // handle HTTP response
    }, function(error) {
      // handle network error
    })
    

      就是这么方便,就是这么简单。 fetch 会先发起一个 option 的请求,确定是否连接成功,然后再发送正式的请求 ,就好比 xhr.readyState === 4 这个一个道理。那有同学就问了,我的逻辑比较复杂 。我的 fetch 要加请求头,参数我要传参传 formData 不是 json。
    我们来看fetch发送formdata:

    fetch(url,{
        method:"post",
        headers:{
            "Content-type":"application:/x-www-form-urlencoded:charset=UTF-8"
        },
        body:"name=admin&password=123456"
    }).then(function(response){
        if(response.ok){
            response.json().then(json => {
                  console.log(json.result)
            })
        }
    }).catch(function(err){
        console.log("Fetch错误:"+err);
    });
    

      发送json格式也非常简单。

    fetch(url,{
        method:"post",
        headers:{
           'Content-Type':'application/json; charset=UTF-8'
        },
        body:JSON.stringify({name:'admin',password:123456})
    }).then(function(response){
        if(response.ok){
            response.json().then(json => {
                  console.log(json.result)
            })
        }
    }).catch(function(err){
        console.log("Fetch错误:"+err);
    });
    

    中止 取消 fetch

    浏览器已经开始为 AbortControllerAbortSignal 接口(也就是Abort API)添加实验性支持,允许像 Fetch 和 XHR 这样的操作在还未完成时被中止 。请参阅接口页面了解更多详情。但是目前对游览器的支持并不很好,所以我们其实可以换一种思路, 取消 fetch 我们可以从另外一个面入手 ---- 可以取消 promise 。原生的当然不行了,所以我们这里用到了 bluebird

    例如多个 fetch:

    
    //传统 promise
    var promises = [];
    for (var i = 0; i < fileNames.length; ++i) {
        promises.push(fs.readFileAsync(fileNames[i]));
    }
    Promise.all(promises).then(function() {
        console.log("done");
    });
    
    // Using Promise.map:
    import Promise from 'bluebird'
    Promise.map(fileNames, function(fileName) {
        // Promise.map awaits for returned promises as well.
        return fs.readFileAsync(fileName);
    }).then(function() {
        console.log("done");
    });
    
    

    终止取消多个 fetch:

    import Promise from 'bluebird'
    Promise.map(fileNames, function(fileName) {
        // Promise.map awaits for returned promises as well.
        return fs.readFileAsync(fileName).then(()=>{
                    //如果flag = true 就中断。
                    if (flag){
                      throw new Error('中断')
                    }
                });;
    }).then(function() {
        console.log("done");
    }).catch(function (err) {
        console.log('Error', err.message)
    });
    

    如果取消单个 promise 可以用 .cancel 方法,具体看 bluebird 文档。

    Axios 的出现

      从文档中我们可以看出为什么这个会火 ,axios 他的功能非常强大,包括 取消请求 ,进度处理等等。但是我们看的是本质还是 ajax ,在基础上进行了封装和功能的添加

    XMLHttpRequests
    支持 Promise

    //一个post请求
    
    axios.post('/user', {
        firstName: 'Fred',
        lastName: 'Flintstone'
      })
      .then(function (response) {
        console.log(response);
      })
      .catch(function (error) {
        console.log(error);
      });
    
    

    结语

      其实我们看出来, ajax 和 Axios 在客户端都是调用 XMLHttpRequests 对象 ,而我们的 fetch 是一个新的游览器对象 。只不过 ajax 和 Axios 区别就是在 封装了简便的方法,并且提供了一个 promise 对象。

    相关文章

      网友评论

          本文标题:如何使用 fetch ,加请求头, ajax 和 fetch 和

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