VDone Demo VDone Demo
Home
  • Articles

    • JavaScript
  • Study Notes

    • JavaScript Tutorial
    • Professional JavaScript
    • ES6 Tutorial
    • Vue
    • React
    • TypeScript: Build Axios from Scratch
    • Git
    • TypeScript
    • JS Design Patterns
  • HTML
  • CSS
  • Technical Docs
  • GitHub Tips
  • Node.js
  • Blog Setup
  • Learning
  • Interviews
  • Miscellaneous
  • Practical Tips
  • Friends
About
Bookmarks
  • Categories
  • Tags
  • Archives
GitHub (opens new window)

Nikolay Tuzov

Backend Developer
Home
  • Articles

    • JavaScript
  • Study Notes

    • JavaScript Tutorial
    • Professional JavaScript
    • ES6 Tutorial
    • Vue
    • React
    • TypeScript: Build Axios from Scratch
    • Git
    • TypeScript
    • JS Design Patterns
  • HTML
  • CSS
  • Technical Docs
  • GitHub Tips
  • Node.js
  • Blog Setup
  • Learning
  • Interviews
  • Miscellaneous
  • Practical Tips
  • Friends
About
Bookmarks
  • Categories
  • Tags
  • Archives
GitHub (opens new window)
  • 初识 TypeScript

  • TypeScript 常用语法

  • ts-axios 项目初始化

  • ts-axios 基础功能实现

    • Handling Request URL Parameters
    • Handling Request Body Data
    • Handling Request Headers
    • Retrieving Response Data
      • Requirements Analysis
      • Defining Interface Types
      • Implementing Response Data Retrieval Logic
      • Writing the Demo
    • Handling Response Headers
    • Handling Response Data
  • ts-axios 异常情况处理

  • ts-axios 接口扩展

  • ts-axios 拦截器实现

  • ts-axios 配置化实现

  • ts-axios 取消功能实现

  • ts-axios 更多功能实现

  • ts-axios 单元测试

  • ts-axios 部署与发布

  • 《TypeScript 从零实现 axios》
  • ts-axios 基础功能实现
HuangYi
2020-01-05
Contents

Retrieving Response Data

# Retrieving Response Data

# Requirements Analysis

In previous chapters, the requests we sent could receive server-returned data at the network level, but at the code level we didn't handle the returned data at all. We want to process the server response data and support Promise-style chaining:

axios({
  method: 'post',
  url: '/base/post',
  data: {
    a: 1,
    b: 2
  }
}).then((res) => {
  console.log(res)
})
1
2
3
4
5
6
7
8
9
10

We want to access the res object, and we expect it to include: the server-returned data data, the HTTP status code status, the status message statusText, response headers headers, the request configuration object config, and the XMLHttpRequest object instance request.

# Defining Interface Types

Based on the requirements, we can define an AxiosResponse interface type:

export interface AxiosResponse {
  data: any
  status: number
  statusText: string
  headers: any
  config: AxiosRequestConfig
  request: any
}
1
2
3
4
5
6
7
8

Additionally, since the axios function returns a Promise object, we can define an AxiosPromise interface that extends the generic Promise<AxiosResponse> interface:

export interface AxiosPromise extends Promise<AxiosResponse> {
}
1
2

This way, when axios returns AxiosPromise type, the parameter in the resolve function will be of AxiosResponse type.

For an AJAX request's response, we can specify the response data type by setting the XMLHttpRequest object's responseType (opens new window) property. So we can add an optional property to the AxiosRequestConfig type:

export interface AxiosRequestConfig {
  // ...
  responseType?: XMLHttpRequestResponseType
}
1
2
3
4

The responseType type is XMLHttpRequestResponseType, which is defined as the string literal type "" | "arraybuffer" | "blob" | "document" | "json" | "text".

# Implementing Response Data Retrieval Logic

First, we need to add an onreadystatechange (opens new window) event handler to the xhr function and make the xhr function return AxiosPromise type.

xhr.ts:

export default function xhr(config: AxiosRequestConfig): AxiosPromise {
  return new Promise((resolve) => {
    const { data = null, url, method = 'get', headers, responseType } = config

    const request = new XMLHttpRequest()

    if (responseType) {
      request.responseType = responseType
    }

    request.open(method.toUpperCase(), url, true)

    request.onreadystatechange = function handleLoad() {
      if (request.readyState !== 4) {
        return
      }

      const responseHeaders = request.getAllResponseHeaders()
      const responseData = responseType && responseType !== 'text' ? request.response : request.responseText
      const response: AxiosResponse = {
        data: responseData,
        status: request.status,
        statusText: request.statusText,
        headers: responseHeaders,
        config,
        request
      }
      resolve(response)
    }

    Object.keys(headers).forEach((name) => {
      if (data === null && name.toLowerCase() === 'content-type') {
        delete headers[name]
      } else {
        request.setRequestHeader(name, headers[name])
      }
    })

    request.send(data)
  })
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41

Note that we also check if responseType is configured in config and set it on request.responseType. In the onreadystatechange event handler, we construct an AxiosResponse type response object and resolve it.

After modifying the xhr function, we also need to update the axios function accordingly:

index.ts:

function axios(config: AxiosRequestConfig): AxiosPromise {
  processConfig(config)
  return xhr(config)
}
1
2
3
4

This completes the Promise-based implementation of the axios function.

# Writing the Demo

We add 2 code snippets to examples/base/app.ts:

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

axios({
  method: 'post',
  url: '/base/post',
  responseType: 'json',
  data: {
    a: 3,
    b: 4
  }
}).then((res) => {
  console.log(res)
})
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22

When we open the browser and run the demo, we find that we can properly log the res variable, which contains all the properties defined in the AxiosResponse type. However, we notice 2 small issues: first, the headers property is a string and we need to parse it into an object; second, in the first request, the received data is a JSON string that also needs to be converted to an object.

In the next section, we'll solve the first issue by processing the response headers.

Edit (opens new window)
#TypeScript
Last Updated: 2026/03/21, 12:14:36
Handling Request Headers
Handling Response Headers

← Handling Request Headers Handling Response Headers→

Recent Updates
01
How I Discovered Disposable Email — A True Story
06-12
02
Animations in Grid Layout
09-15
03
Renaming a Git Branch
08-11
More Articles >
Theme by VDone | Copyright © 2026-2026 Nikolay Tuzov | MIT License | Telegram
  • Auto
  • Light Mode
  • Dark Mode
  • Reading Mode