zoukankan      html  css  js  c++  java
  • fetch 如何请求数据

    一 序言

    在 传统Ajax 时代,进行 API 等网络请求都是通过XMLHttpRequest或者封装后的框架进行网络请求,然而配置和调用方式非常混乱,对于刚入门的新手并不友好。今天我们介绍的Fetch提供了一个更好的替代方法,它不仅提供了一种简单,合乎逻辑的方式来跨网络异步获取资源,而且可以很容易地被其他技术使用,例如 Service Workers。

    二 与Ajax对比

    使用Ajax请求一个 JSON 数据一般是这样:

    var xhr = new XMLHttpRequest();
    xhr.open('GET', url/file,true);
    xhr.onreadystatechange = function() {
       if(xhr.readyState==4){
            if(xhr.status==200){
                var data=xhr.responseText;
                 console.log(data);
       }
    };
    xhr.onerror = function() {
      console.log("Oh, error");
    };
    xhr.send();

    同样我们使用fetch请求JSON数据:

    fetch(url).then(response => response.json())//解析为可读数据
      .then(data => console.log(data))//执行结果是 resolve就调用then方法
      .catch(err => console.log("Oh, error", err))//执行结果是 reject就调用catch方法

    从两者对比来看,fetch代码精简许多,业务逻辑更清晰明了,使得代码易于维护,可读性更高。
    总而言之,Fetch 优点主要有:

    1. 语法简洁,更加语义化,业务逻辑更清晰

    2. 基于标准 Promise 实现,支持 async/await

    3. 同构方便,使用isomorphic-fetch

    三 Promise简介

    由于 Fetch API 是基于 Promise 设计,接下来我们简单介绍下Promise工作流程,方便大家更好理解Fetch。

    fetch方法返回一个Promise对象, 根据 Promise Api 的特性, fetch可以方便地使用then方法将各个处理逻辑串起来, 使用 Promise.resolve() 或 Promise.reject() 方法将分别返会肯定结果的Promise或否定结果的Promise, 从而调用下一个then 或者 catch。一旦then中的语句出现错误, 也将跳到catch中。

    四 请求常见数据格式

    接下来将介绍如何使用fetch请求本地文本数据,请求本地JSON数据以及请求网络接口。其实操作相比与Ajax,简单很多!

    //HTML部分
      <div class="container">
        <h1>Fetch Api sandbox</h1>
        <button id="button1">请求本地文本数据</button>
        <button id="button2">请求本地json数据</button>
        <button id="button3">请求网络接口</button>
        <br><br>
        <div id="output"></div>
      </div>
      <script src="app.js"></script>

    1.fetch请求本地文本数据

    本地有一个test.txt文档,通过以下代码就可以获取其中的数据,并且显示在页面上。

    document.getElementById('button1').addEventListener('click',getText);
    function getText(){
      fetch("test.txt")
          .then((res) => res.text())//注意:此处是res.text()
          .then(data => {
            console.log(data);
            document.getElementById('output').innerHTML = data;
          })
          .catch(err => console.log(err));
    }

    2.fetch请求本地JSON数据

    本地有个posts.json数据,与请求本地文本不同的是,得到数据后还要用forEach遍历,最后呈现在页面上。

    document.getElementById('button2').addEventListener('click',getJson);
    function getJson(){
      fetch("posts.json")
          .then((res) => res.json())
          .then(data => {
            console.log(data);
            let output = '';
            data.forEach((post) => {
              output += `<li>${post.title}</li>`;
            })
            document.getElementById('output').innerHTML = output;
          })
          .catch(err => console.log(err));
    }

    3.fetch请求网络接口

    获取https://api.github.com/users中的数据,做法与获取本地JSON的方法类似,得到数据后,同样要经过处理

     
    document.getElementById('button3').addEventListener('click',getExternal);
    function getExternal(){
      // https://api.github.com/users
      fetch("https://api.github.com/users")
          .then((res) => res.json())
          .then(data => {
            console.log(data);
            let output = '';
            data.forEach((user) => {
              output += `<li>${user.login}</li>`;
            })
            document.getElementById('output').innerHTML = output;
          })
          .catch(err => console.log(err));
    }

    一、fetch

      fetch是一种XMLHttpRequest的一种替代方案,在工作当中除了用ajax获取后台数据外我们还可以使用fetch、axios来替代ajax

     二、安装

      

      执行npm install whatwg-fetch --save即可安装。

      为了兼容老版本浏览器,还需要安装npm install es6-promise --save

    三、fetch的基本使用 

      

    复制代码
    npm install whatwg-fetch --save
    npm install es6-promise --save
    import 'es6-promise'
    import 'whatwg-fetch'
    
    fetch(url,options).then((res)=>{
      console.log(res);
    },function(err){
      console.log(err)
    })
    复制代码

    说明:

        1、fetch的返回值是一个promise对象

        2、options

            method:HTTP请求方式,默认是GET

    复制代码
       body:请求的参数
    
            fetch('/xxx', {
    
                   method: 'post',
    
                   body:'username=zhangsan&age=17'
    
     
    
           });
    复制代码

            headers:HTTP请求头

                因为一般使用JSON数据格式,所以设置ContentType为application/json

                credentials:默认为omit,忽略的意思,也就是不带cookie还有两个参数,same-origin,意思就是同源请求带cookie;include,表示无论跨域还是同源请求都会带cookie

        3、在.then里面第一个回调函数中处理response

            status(number): HTTP返回的状态码,范围在100-599之间

            statusText(String): 服务器返回的状态文字描述

            headers: HTTP请求返回头

            body: 返回体,这里有处理返回体的一些方法

            text(): 将返回体处理成字符串类型

           json(): 返回结果和 JSON.parse(responseText)一样

           blob(): 返回一个Blob,Blob对象是一个不可更改的类文件的二进制数据

    如果请求一个XML格式文件,则调用response.text。如果请求图片,使用response.blob方法

    注意:

      cookie传递必须在header参数里面加上credentials: 'include',才会如xhr一样将当前cookies带到请求中去

     四、get、post请求方式

      1、get

    复制代码
    var result = fetch('url', {
            credentials: 'include',
            headers: {
                'Accept': 'application/json, text/plain, */*',
            },    
     });
    复制代码

      2、post

    复制代码
    var result = fetch('/api/post', {
            method: 'POST',
            credentials: 'include',
            headers: {
                'Accept': 'application/json, text/plain, */*',
                'Content-Type': 'application/x-www-form-urlencoded'
            },
            // 注意 post 时候参数的形式
            body: "a=100&b=200"
        });
    复制代码

    五、封装get和post方法

      1、get

    复制代码
    import 'es6-promise'
    import 'whatwg-fetch'
    
    export default (url)=>({
        var result = fetch(url, {
            credentials: 'include',
            headers: {
                'Accept': 'application/json, text/plain, */*',
            },    
       })
       .then(res=>res.json());
       
       return result
    })
    复制代码

      2、post

    复制代码
    import 'es6-promise'
    import 'whatwg-fetch'
    import qs from 'qs';
    export default (url,data)=>({
        var result = fetch(url, {
            method: 'POST',
            credentials: 'include',
            headers: {
                'Accept': 'application/json, text/plain, */*',
                'Content-Type': 'application/x-www-form-urlencoded'
            },
            // 注意 post 时候参数的形式
            body: qs(data)
        })
        .then(res=>res.json())
        
        return result;
    })
    复制代码

     六、fetch与axios的区别

    复制代码
    axios("http://xxx/xxx.json?a=123'").then((res)=>{
         console.log(res)//这里的r是响应结果
    })
    
    fetch("http://www.baidu.com").then((res)=>{
            console.log(res);//是一个综合各种方法的对象,并不是请求的数据
    })
    复制代码

    fetch返回的是一个未处理的方法集合,我们可以通过这些方法得到我们想要的数据类型。如果我们想要json格式,就执行response.json(),如果我们想要字符串就response.text()

    axios 

            1、从浏览器中创建 XMLHttpRequest

            2、从 node.js 发出 http 请求

            3、支持 Promise API

            4、拦截请求和响应

            5、转换请求和响应数据

            6、自动转换JSON数据

            7、客户端支持防止CSRF/XSRF

    fetch:

        符合关注分离,没有将输入、输出和用事件来跟踪的状态混杂在一个对象里

        更加底层,提供的API丰富(request, response)

        脱离了XHR,是ES规范里新的实现方式

    1、fetchtch只对网络请求报错,对400,500都当做成功的请求,需要封装去处理

    2、fetch默认不会带cookie,需要添加配置项

    3、fetch不支持abort,不支持超时控制,使用setTimeout及Promise.reject的实

    现的超时控制并不能阻止请求过程继续在后台运行,造成了量的浪费

    4、fetch没有办法原生监测请求的进度,而XHR可以



  • 相关阅读:
    宿主机( win 7 系统) ping 虚拟机VMware( cent os 6.6 ) 出现“请求超时”或者“无法访问目标主机”的解决方法
    Java实现 LeetCode 23 合并K个排序链表
    Java实现 LeetCode 23 合并K个排序链表
    Java实现 LeetCode 23 合并K个排序链表
    Java实现 LeetCode 22 括号生成
    Java实现 LeetCode 22 括号生成
    Java实现 LeetCode 22 括号生成
    Java实现 LeetCode 21 合并两个有序链表
    Java实现 LeetCode 21 合并两个有序链表
    Java实现 LeetCode 21 合并两个有序链表
  • 原文地址:https://www.cnblogs.com/yebai/p/10161485.html
Copyright © 2011-2022 走看看