zoukankan      html  css  js  c++  java
  • ajax 封装(集中 认证、错误、请求loading处理)

    一、为什么要对 ajax 进行封装:    (在使用antd pro 开发项目时,里面默认是把请求进行了封装的,放在 utils/request.js 中。使用起来非常方便   https://pro.ant.design/docs/server-cn  )

      1、便于统一处理 POST,GET 等请求参数,请求头,以及错误提示信息等。甚至 loading处理 。

      2、一个项目中 请求头、错误处理、loading 处理一把都是一样的。封装之后,层次结构清晰;代码减少,且页面中的逻辑只要关心对应的逻辑就可以了。

      3、如果 请求上有token 判断是否登入,接口还要引导登入。

         请求中不同域判断判断是否登入,需要前端手动在header上加上tooken。

      4、如果 后端请求超时、以及 后端服务器 宕机,要做好应对机制。跳转到指定页面 或者 弹出提示框。这些都是可以在封装的ajax上处理的。

      5、网络请求状态码为200,但接口态码非200(或 0000)的Response 包装成异常信息。这样页面中的业务逻辑就不需要判断 接口状态码非成功的情况了。

      6、浏览器和服务器,ip地址通的话,服务器才会有返回码。如果浏览器是断网的话,服务器是没有返回错误码的。下面代码是基于axios封装的错误处理。

    /**
     * 异常处理程序
     */
    const errorHandler = error => {
      if (error.response) {
        // 请求已发出,但服务器响应的状态码不在 2xx 范围内
        console.log(error.response)
        const errorText = codeMessage[error.response.status] || error.response.statusText
        const { status, config } = error.response
        console.log(`请求错误 ${status}:${config.url}${errorText}`)
      } else {
        // 请求没有响应。即网络发生异常,无法连接服务器,比如  浏览器或服务器  断网。
        console.log('网络异常', error.message)
      }
      console.log(error.config)
    }

    二、axios 的二次封装:https://www.mmxiaowu.com/article/589af8cde9be1c5b21ef8e9c 或 https://blog.csdn.net/weixin_33769125/article/details/93993438(推荐这个)

      axios 官网文档:https://www.kancloud.cn/yunye/axios/234845

      说明:axios 拦截器,return false(或者抛出异常)。就不会发送请求出去。

      1、错误反馈:

    const codeMessage = {
      200: '服务器成功返回请求的数据。',
      201: '新建或修改数据成功。',
      202: '一个请求已经进入后台排队(异步任务)。',
      204: '删除数据成功。',
      400: '发出的请求有错误,服务器没有进行新建或修改数据的操作。',
      401: '用户没有权限(令牌、用户名、密码错误)。',
      403: '用户得到授权,但是访问是被禁止的。',
      404: '发出的请求针对的是不存在的记录,服务器没有进行操作。',
      406: '请求的格式不可得。',
      410: '请求的资源被永久删除,且不会再得到的。',
      422: '当创建一个对象时,发生一个验证错误。',
      500: '服务器发生错误,请检查服务器。',
      502: '网关错误。',
      503: '服务不可用,服务器暂时过载或维护。',
      504: '网关超时。',
    };

    三、我对 axios 的二次封装:

      封装方式1:

    import axios from 'axios'
    // import Qs from 'qs'
    
    const codeMessage = {
      200: '服务器成功返回请求的数据。',
      201: '新建或修改数据成功。',
      202: '一个请求已经进入后台排队(异步任务)。',
      204: '删除数据成功。',
      400: '发出的请求有错误,服务器没有进行新建或修改数据的操作。',
      401: '用户没有权限(令牌、用户名、密码错误)。',
      403: '用户得到授权,但是访问是被禁止的。',
      404: '发出的请求针对的是不存在的记录,服务器没有进行操作。',
      406: '请求的格式不可得。',
      410: '请求的资源被永久删除,且不会再得到的。',
      422: '当创建一个对象时,发生一个验证错误。',
      500: '服务器发生错误,请检查服务器。',
      502: '网关错误。',
      503: '服务不可用,服务器暂时过载或维护。',
      504: '网关超时。'
    }
    
    /**
     * 异常处理程序
     */
    const errorHandler = error => {
      alert('请求失败')
      if (error.response) {
        // 请求已发出,但服务器响应的状态码不在 2xx 范围内
        console.log(error.response)
        const errorText = codeMessage[error.response.status] || error.response.statusText
        const { status, config } = error.response
        console.log(`请求错误 ${status}:${config.url}${errorText}`)
      } else {
        // 请求没有响应。即网络发生异常,无法连接服务器,比如  浏览器或服务器  断网。
        console.log('网络异常:与服务器断开链接')
      }
      console.log(error.config)
    }
    
    // 设置请求超时时间
    axios.defaults.timeout = 10000
    
    // 设置post请求头
    axios.defaults.headers.post['Content-Type'] = 'application/x-www-form-urlencoded;charset=UTF-8'
    
    // 请求拦截
    axios.interceptors.request.use(config => {
      // 在发送请求之前做些什么 验证token之类的
      alert('发送请求前')
    
      return config
    }, error => {
      alert('抛出错误')
      // 对请求错误做些什么
      return Promise.error(error)
    })
    
    // 响应拦截
    axios.interceptors.response.use(response => {
      // 对响应数据做点什么
      alert('响应请求后')
      return response
    }, error => {
      alert('响应错误')
      // 对响应错误做点什么
      return Promise.reject(error)
    })
    
    // 封装get方法和post方法
    
    /**
     * get方法,对应get请求
     * @param {String} url [请求的url地址]
     * @param {Object} params [请求时携带的参数]
     */
    export function get (url, params) {
      return new Promise((resolve, reject) => {
        axios.get(url, {
          params: params
        }).then(res => {
          resolve(res.data)
        }).catch(err => {
          errorHandler(err)
          reject(err)
        })
      })
    }
    
    /**
    * post方法,对应post请求
    * @param {String} url [请求的url地址]
    * @param {Object} params [请求时携带的参数]
    */
    export function post (url, params) {
      return new Promise((resolve, reject) => {
        axios.post(url, params)
          .then(res => {
            resolve(res.data)
          })
          .catch(err => {
            errorHandler(err)
            reject(err)
          })
      })
    }

      封装方式2:

      

    强调下:页面中 所有  请求回来的数据,一定要做好 undefined (没有这个字段时,js中这个字段值就是undefined)、null 引起的报错机制。这不是接口程序错误,这是正常情况的数据。比如当天报名人员信息,没有人报名,数据库中当然是没有数据的。

    最里面那层的属性是 undefined和null 是不会报错的,但是上一层属性一定要判断是不是undefined或null。使用逻辑运算符就可以。

    data || {}   //  data 对象没有数据,需要给个默认的{ } 或 []

    说明下: 后端返回的字段对应的数据,数据类型是不会变的(可能会是null),如果 返回的数据类型错了(比如应该是一个对象,结果返回一个字符串回来),那就是后端的问题了,需要他们处理。

    最新的 es 好像 将要有一个新的API 解决这个问题 :Optional Chaining        https://www.jianshu.com/p/e9ed7660034e


    ajax 响应数据处理

      场景说明:前后端分离的开发环境下,前后端并行开始时势必会产生双方定义字段完全不统一的问题,实际开发中后台会根据需求更换字段。https://blog.csdn.net/qq_15390381/article/details/103803523

           如果返回的数据只是在ajax回调函数中使用下,后台改了,前端同步去改,问题不是很大;如果返回的字段在其他很多地方都有使用的话,那改起来就比较麻烦。需要在所有引用这个字段的地方,都去修改。如:

    <!-- 这里的name直接是根据接口返回数据的字段定的,一但后台接口字段改了,其它的使用这个字段的地方都要改 -->
    <h3>{{userMsg.name}}</h3>
          ajax(url, res => {
            this.userMsg = res.data
          })
    
        /* res.data返回的对象是:  {
            name: '',
            age: '',
            idCode: '',
            phone: '',
            ...
          } */

      优化思路:页面中使用后台接口的字段,都是 js 自己命名的,不随后台接口字段而改变。但是后台的数据响应回来后,做一个字段的映射。把自己命名的字段和接口返回的字段对应起来【两种的命名可以相同也可以不同,互不影响】。

           优点是,① 可以给相应字段 设置默认值;② 后端接口变动,只要改一下映射关系就可以了;③ 后端接口数据很多时,可以只映射需要的字段数据。

           缺点是,如果映射的对象 层级比较多,映射就不好处理了。(所以要不要进行字段映射,完全看后台字段是不是会经常改动。一般接口字段都是稳定,要改也是个别几个,所以基本不用去映射

      实现方案:                                    参考,https://blog.csdn.net/qq_15390381/article/details/103803523  或  http://www.mamicode.com/info-detail-2932906.html

        后续更新。。。

  • 相关阅读:
    linux设备模型
    dma
    POSIX thread
    Network: IP QoS
    TCP: sliding window of flow control
    TCPIP: UDP/TCP checksum
    Hebrew: Learning Resources
    Vivado: Uninstall Vivado on ubuntu/linux
    HLS: vivado_hls compile fail, csim and csyn error, no ip generated for udpLoopback and toe
    HLS: High-Level Synthesis Operators
  • 原文地址:https://www.cnblogs.com/wfblog/p/12089942.html
Copyright © 2011-2022 走看看