美文网首页
2-4、获取响应数据

2-4、获取响应数据

作者: Eileen_1d88 | 来源:发表于2019-12-05 11:17 被阅读0次

    上一节,我们从网络层面上获取到了服务器端的响应,但是从代码层面上来看,没有接收响应数据的代码,那么接下来我们要做的就是这一部分的工作,我们希望得到的结果是:

    axios({
      method: 'post',
      url: '/base/post',
      data: {
        a: 1,
        b: 2
      }
    }).then((res) => {
      console.log(res)
    })
    

    我们拿到的res对象,希望里面包括响应数据data,响应头headers,状态码status,状态说明statusText,请求配置对象config,以及请XMLHttpRequest的对象实例request。

    • 定义AxiosResponse接口类型
    interface AxiosResponse {
      status: number,
      statusText: string,
      config: AxiosRequestConfig,
      headers: any,
      request: any,
      data: any
    }
    
    • axios返回一个promise对象,所以这里也定义一个axiosPromise接口类型
    // 当axios请求返回一个AxiosPromise,
    // 那么resolve中返回的就是AxiosResponse类型的响应数据
    interface AxiosPromise extends Promise<AxiosResponse> {}
    

    对于一个ajax请求的respons,我们是可以指定它的响应数据的类型的,通过设置XMLHttpRequest对象的responseType属性,于是我们可以给AxiosRequestConfig增加一个属性responseType

    interface AxiosRequestConfig {
      url: string,
      method?: Method,
      headers?: any,
      data?: any,
      params?: any,
      responseType?: XMLHttpRequestResponseType
    }
    

    responseType的类型是XMLHttpRequestResponseType类型,它的值可以是""、arraybuffer、blob、document、json、text、ms-stream 。

    实现获取响应数据的逻辑

    首先我们要在xhr中增加onreadystatechange事件的处理函数,并且让xhr函数返回AxiosPromise类型

    import { AxiosRequestConfig, AxiosPromise, AxiosResponse } from "./types";
    
    export default function xhr(config: AxiosRequestConfig): AxiosPromise {
      return new Promise((resolve, reject) => {
        // method和data可能没有, 所以给出默认值
        const { url, method = 'get', data = null, headers, responseType } = config
        const request = new XMLHttpRequest()
        if (responseType) {
          request.responseType = responseType
        }
        request.open(method.toUpperCase(), url)
        request.onreadystatechange = function handleLoad() {
          // request.readyState不是4,说明请求还未返回
          if (request.readyState !== 4) {
            return
          }
          const responseHeaders = request.getAllResponseHeaders()
          const responseData = responseType && responseType !== 'text' ? request.response : request.responseText
          const response: AxiosResponse = {
            data: responseData,
            headers: responseHeaders,
            status: request.status,
            statusText: request.statusText,
            config,
            request
          }
          resolve(response)
        }
        Object.keys(headers).forEach((name) => {
          request.setRequestHeader(name, headers[name])
        })
        request.send(data)
      })
    }
    

    src/index.ts

    export default function axios(config: AxiosRequestConfig): AxiosPromise {
      processConfig(config)
      return xhr(config)
    }
    

    这样,就实现了axios的promise化

    编写demo
    axios({
      method: 'post',
      url: '/api/base/post',
      // headers: {
      //   'content-type': 'application/json;'
      // },
      data: {
        a: 1,
        b: 2
      }
    }).then((res) => {
      console.log(res)
    })
    axios({
      method: 'post',
      url: '/api/base/post',
      responseType: 'json',
      data: {
        a: 3,
        b: 4
      }
    }).then((res) => {
      console.log(res)
    })
    

    运行demo之后,我们发现2个问题,第一是headers是json字符串,第二是第一个请求的data是json字符串。
    那么接下来,我们将要对headers进行处理

    相关文章

      网友评论

          本文标题:2-4、获取响应数据

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