yyz notes yyz notes
首页
  • RBAC权限设计
  • 架构图标设计
  • 账号体系
  • python基础
  • python高级
  • python模块
  • python设计模式
  • python数据结构与算法
  • django
  • django-DRF
  • flask
  • 直接设计开源pip包
  • 直接设计开源项目
  • python示例题/脚本
  • python面试题
  • golang基础
  • golang高级
  • golang常用组件
  • gin框架
  • es6
  • javascript
  • react
  • vue
  • TypeScript
  • mysql
  • redis
  • minio
  • elasticsearch
  • mongodb
  • 消息队列
  • 自动化测试
  • 操作系统

    • linux
    • windows
  • nginx
  • docker
  • k8s
  • git
  • ldap
  • 学习
  • 面试
  • 心情杂货
  • 实用技巧
  • 友情链接
关于
收藏
  • 分类
  • 标签
  • 归档
GitHub (opens new window)

益章

可乐鸡翅
首页
  • RBAC权限设计
  • 架构图标设计
  • 账号体系
  • python基础
  • python高级
  • python模块
  • python设计模式
  • python数据结构与算法
  • django
  • django-DRF
  • flask
  • 直接设计开源pip包
  • 直接设计开源项目
  • python示例题/脚本
  • python面试题
  • golang基础
  • golang高级
  • golang常用组件
  • gin框架
  • es6
  • javascript
  • react
  • vue
  • TypeScript
  • mysql
  • redis
  • minio
  • elasticsearch
  • mongodb
  • 消息队列
  • 自动化测试
  • 操作系统

    • linux
    • windows
  • nginx
  • docker
  • k8s
  • git
  • ldap
  • 学习
  • 面试
  • 心情杂货
  • 实用技巧
  • 友情链接
关于
收藏
  • 分类
  • 标签
  • 归档
GitHub (opens new window)
  • ES6 教程笔记

  • JavaScript教程笔记

  • React笔记

  • Vue笔记

  • TypeScript 从零实现 axios

    • 初识 TypeScript

    • TypeScript 常用语法

    • ts-axios 项目初始化

    • ts-axios 基础功能实现

      • 处理请求 url 参数
      • 处理请求 body 数据
        • 需求分析
        • transformRequest 函数实现
        • 实现请求 body 处理逻辑
        • 编写 demo
      • 处理请求 header
      • 获取响应数据
      • 处理响应 header
      • 处理响应 data
    • ts-axios 异常情况处理

    • ts-axios 接口扩展

    • ts-axios 拦截器实现

    • ts-axios 配置化实现

    • ts-axios 取消功能实现

    • ts-axios 更多功能实现

    • ts-axios 单元测试

    • ts-axios 部署与发布

  • 前端
  • TypeScript 从零实现 axios
  • ts-axios 基础功能实现
yizhang
2020-01-05
目录

处理请求 body 数据

# 处理请求 body 数据

# 需求分析

我们通过执行 XMLHttpRequest 对象实例的 send 方法来发送请求,并通过该方法的参数设置请求 body 数据,我们可以去 mdn (opens new window) 查阅该方法支持的参数类型。

我们发现 send 方法的参数支持 Document 和 BodyInit 类型,BodyInit 包括了 Blob, BufferSource, FormData, URLSearchParams, ReadableStream、USVString,当没有数据的时候,我们还可以传入 null。

但是我们最常用的场景还是传一个普通对象给服务端,例如:

axios({
  method: 'post',
  url: '/base/post',
  data: {
    a: 1,
    b: 2
  }
})
1
2
3
4
5
6
7
8

这个时候 data是不能直接传给 send 函数的,我们需要把它转换成 JSON 字符串。

# transformRequest 函数实现

根据需求分析,我们要实现一个工具函数,对 request 中的 data 做一层转换。我们在 helpers 目录新建 data.ts 文件。

helpers/data.ts:

import { isPlainObject } from './util'

export function transformRequest (data: any): any {
  if (isPlainObject(data)) {
    return JSON.stringify(data)
  }
  return data
}
1
2
3
4
5
6
7
8

helpers/util.js:

export function isPlainObject (val: any): val is Object {
  return toString.call(val) === '[object Object]'
}
1
2
3

这里为什么要使用 isPlainObject 函数判断,而不用之前的 isObject 函数呢,因为 isObject 的判断方式,对于 FormData、ArrayBuffer 这些类型,isObject 判断也为 true,但是这些类型的数据我们是不需要做处理的,而 isPlainObject 的判断方式,只有我们定义的普通 JSON 对象才能满足。

helpers/url.ts:

if (isDate(val)) {
  val = val.toISOString()
} else if (isPlainObject(val)) {
  val = JSON.stringify(val)
}
1
2
3
4
5

对于上节课我们对请求参数值的判断,我们也应该用 isPlainObject 才更加合理。

helpers/util.js

// export function isObject (val: any): val is Object {
//   return val !== null && typeof val === 'object'
// }
1
2
3

既然现在 isObject 方法不再使用,我们先将其注释。

# 实现请求 body 处理逻辑

index.ts:

import { transformRequest } from './helpers/data'

```typescript
function processConfig (config: AxiosRequestConfig): void {
  config.url = transformURL(config)
  config.data = transformRequestData(config)
}

function transformRequestData (config: AxiosRequestConfig): any {
  return transformRequest(config.data)
}
1
2
3
4
5
6
7
8
9
10
11

我们定义了 transformRequestData 函数,去转换请求 body 的数据,内部调用了我们刚刚实现的的 transformRequest 方法。

然后我们在 processConfig 内部添加了这段逻辑,在处理完 url 后接着对 config 中的 data 做处理。

# 编写 demo

axios({
  method: 'post',
  url: '/base/post',
  data: {
    a: 1,
    b: 2
  }
})

const arr = new Int32Array([21, 31])

axios({
  method: 'post',
  url: '/base/buffer',
  data: arr
})
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16

我们在 examples/base/app.ts 添加 2 段代码,第一个 post 请求的 data 是一个普通对象,第二个请求的 data 是一个 Int32Array 类型的数据,它是可以直接传给 XMLHttpRequest 对象的 send 方法的。

router.post('/base/post', function(req, res) {
  res.json(req.body)
})

router.post('/base/buffer', function(req, res) {
  let msg = []
  req.on('data', (chunk) => {
    if (chunk) {
      msg.push(chunk)
    }
  })
  req.on('end', () => {
    let buf = Buffer.concat(msg)
    res.json(buf.toJSON())
  })
})
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16

我们接着在 examples/server.js 中添加 2 个路由,分别针对这俩种请求,返回请求传入的数据。

然后我们打开浏览器运行 demo,看一下结果,我们发现 /base/buffer 的请求是可以拿到数据,但是 base/post 请求的 response 里却返回的是一个空对象,这是什么原因呢?

实际上是因为我们虽然执行 send 方法的时候把普通对象 data 转换成一个 JSON 字符串,但是我们请求header 的 Content-Type 是 text/plain;charset=UTF-8,导致了服务端接受到请求并不能正确解析请求 body 的数据。

知道这个问题后,下面一节课我们来实现对请求 header 的处理。

编辑 (opens new window)
#TypeScript
上次更新: 2023/05/17, 23:08:21
处理请求 url 参数
处理请求 header

← 处理请求 url 参数 处理请求 header→

最近更新
01
配置yun源
05-24
02
linux-配置python虚拟环境
05-24
03
linux文件目录管理
05-24
更多文章>
Theme by Vdoing | Copyright © 2023-2023 yizhang | MIT License
  • 跟随系统
  • 浅色模式
  • 深色模式
  • 阅读模式