当前位置:   article > 正文

TypeScript 从零实现 axios 0x4 基础功能实现——请求body和header、响应数据处理_ts语言网络请求设置header

ts语言网络请求设置header

请求body数据处理

处理逻辑实现

./src/helpers/data.ts

  1. import { isPlainObject } from './util'
  2. export function transformRequest (data: any) : any {
  3. if (isPlainObject(data)) {
  4. return JSON.stringify(data)
  5. }
  6. return data
  7. }

./src/helper/util.ts 

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

 加入处理流程

  1. // ./src/index.ts
  2. import { AxiosRequestConfig } from './types'
  3. import xhr from './xhr'
  4. import { buildURL } from './helpers/url'
  5. import { transformRequest } from './helpers/data'
  6. function axios(config: AxiosRequestConfig): void {
  7. // TODO
  8. processConfig(config)
  9. xhr(config)
  10. }
  11. function processConfig(config: AxiosRequestConfig): void {
  12. config.url = transformURL(config)
  13. config.data = transformRequestData(config)
  14. }
  15. function transformURL(config: AxiosRequestConfig): string {
  16. const { url, params } = config
  17. return buildURL(url, params)
  18. }
  19. function transformRequestData(config: AxiosRequestConfig): any {
  20. return transformRequest(config.data)
  21. }
  22. export default axios

测试

./example/base/app.ts

  1. axios({
  2. method: 'get',
  3. url: '/base/get?foo=bar',
  4. params: {
  5. bar: 'baz'
  6. }
  7. })
  8. // 请求body数据测试
  9. axios({
  10. method: 'post',
  11. url: '/base/post',
  12. data: {
  13. a: 1,
  14. b: 2
  15. }
  16. })

 ./examples/server.js

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

 

请求header数据处理

处理逻辑实现

  1. // ./src/helpers/headers.ts
  2. import { isPlainObject } from './util'
  3. function normalizeHeaderName (headers: any, normalizeName: string) : void {
  4. if (!headers) return
  5. Object.keys(headers).forEach(name => {
  6. if (name !== normalizeName && name.toUpperCase() === normalizeName.toUpperCase()) {
  7. headers[normalizeName] = headers[name]
  8. delete headers[name]
  9. }
  10. })
  11. }
  12. export function processHeaders (headers: any, data: any): any {
  13. normalizeHeaderName(headers, 'Content-Type')
  14. if (isPlainObject(data)) {
  15. if (headers && !headers['Content-Type']) {
  16. headers['Content-Type'] = 'application/json;charset=utf-8'
  17. }
  18. }
  19. return headers
  20. }

新增类型定义

./src/types/index.ts

  1. export interface AxiosRequestConfig {
  2. url: string
  3. method?: Method
  4. data?: any
  5. params?: any
  6. headers?: any
  7. }

将headers处理加入流程

./src/index.ts

  1. function processConfig(config: AxiosRequestConfig): void {
  2. config.url = transformURL(config)
  3. config.headers = transformHeaders(config)
  4. config.data = transformRequestData(config)
  5. }
  6. function transformHeaders (config: AxiosRequestConfig): any {
  7. const { headers = {}, data } = config
  8. return processHeaders(headers, data)
  9. }

设置头信息

  1. // ./xhr.ts
  2. import { AxiosRequestConfig } from './types'
  3. export default function xhr(config: AxiosRequestConfig) {
  4. const { data = null, url, method = 'get', headers } = config
  5. const request = new XMLHttpRequest()
  6. request.open(method.toUpperCase(), url, true)
  7. Object.keys(headers).forEach(name => {
  8. if (data === null && name.toLowerCase() === 'content-type') {
  9. delete headers[name]
  10. } else {
  11. request.setRequestHeader(name, headers[name])
  12. }
  13. })
  14. request.send(data)
  15. }

测试

./example/base/app.ts

  1. axios({
  2. method: 'post',
  3. url: '/base/post',
  4. data: {
  5. a: 1,
  6. b: 2
  7. }
  8. })
  9. axios({
  10. method: 'post',
  11. url: '/base/post',
  12. headers: {
  13. 'content-type': 'application/json',
  14. 'Accept': 'application/json, text/plain, */*'
  15. },
  16. data: {
  17. a: 1,
  18. b: 2
  19. }
  20. })
  21. const paramsString = 'q=URLUtils.searchParams&topic=api'
  22. const searchParams = new URLSearchParams(paramsString)
  23. axios({
  24. method: 'post',
  25. url: '/base/post',
  26. data: searchParams
  27. })

获取响应数据

 接口定义

  1. // ./src/type/index.ts
  2. export type Method =
  3. | 'get'
  4. | 'GET'
  5. | 'delete'
  6. | 'DELETE'
  7. | 'head'
  8. | 'HEAD'
  9. | 'options'
  10. | 'OPTIONS'
  11. | 'post'
  12. | 'POST'
  13. | 'put'
  14. | 'PUT'
  15. | 'patch'
  16. | 'PATCH'
  17. export interface AxiosRequestConfig {
  18. url: string
  19. method?: Method
  20. data?: any
  21. params?: any
  22. headers?: any
  23. responseType?: XMLHttpRequestResponseType
  24. }
  25. export interface AxiosResponse {
  26. data: any
  27. status: number
  28. statusText: string
  29. headers: any
  30. config: AxiosRequestConfig
  31. request: any
  32. }
  33. export interface AxiosPromise extends Promise<AxiosResponse> {
  34. }

逻辑实现

  1. // ./xhr.ts
  2. import { AxiosRequestConfig, AxiosPromise, AxiosResponse } from './types'
  3. import { parseHeaders } from './helpers/headers'
  4. export default function xhr(config: AxiosRequestConfig): AxiosPromise {
  5. return new Promise((resolve) => {
  6. const { data = null, url, method = 'get', headers, responseType } = config
  7. const request = new XMLHttpRequest()
  8. if (responseType) {
  9. request.responseType = responseType
  10. }
  11. request.open(method.toUpperCase(), url, true)
  12. request.onreadystatechange = function handleLoad () {
  13. if (request.readyState !== 4) {
  14. return
  15. }
  16. const responseHeaders = parseHeaders(request.getAllResponseHeaders())
  17. const responseData = responseType !== 'text' ? request.response : request.responseText
  18. const response : AxiosResponse = {
  19. data: responseData,
  20. status: request.status,
  21. statusText: request.statusText,
  22. headers: responseHeaders,
  23. config,
  24. request
  25. }
  26. resolve(response)
  27. }
  28. Object.keys(headers).forEach(name => {
  29. if (data === null && name.toLowerCase() === 'content-type') {
  30. delete headers[name]
  31. } else {
  32. request.setRequestHeader(name, headers[name])
  33. }
  34. })
  35. request.send(data)
  36. })
  37. }

// ./src/helpers/headers.ts 

  1. export function parseHeaders (headers: string) : any {
  2. let parsed = Object.create(null)
  3. if (!headers) {
  4. return parsed
  5. }
  6. headers.split('\r\n').forEach(line => {
  7. let [key, val] = line.split(':')
  8. key = key.trim().toLowerCase()
  9. if (!key) {
  10. return
  11. }
  12. if (val) {
  13. val = val.trim()
  14. }
  15. parsed[key] = val
  16. })
  17. return parsed
  18. }

 ./src/helpers/data.ts 

  1. export function transformResponse(data: any) : any {
  2. if (typeof data === 'string') {
  3. try {
  4. data = JSON.parse(data)
  5. } catch (e) {
  6. //
  7. }
  8. }
  9. return data
  10. }

流程加入

  1. // ./src/index.ts
  2. import { AxiosRequestConfig, AxiosPromise, AxiosResponse } from './types'
  3. import xhr from './xhr'
  4. import { buildURL } from './helpers/url'
  5. import { transformRequest, transformResponse } from './helpers/data'
  6. import { processHeaders } from './helpers/headers'
  7. function axios(config: AxiosRequestConfig): AxiosPromise {
  8. // TODO
  9. processConfig(config)
  10. return xhr(config).then(res => {
  11. return transformResponseData(res)
  12. })
  13. }
  14. function processConfig(config: AxiosRequestConfig): void {
  15. config.url = transformURL(config)
  16. config.headers = transformHeaders(config)
  17. config.data = transformRequestData(config)
  18. }
  19. function transformURL(config: AxiosRequestConfig): string {
  20. const { url, params } = config
  21. return buildURL(url, params)
  22. }
  23. function transformRequestData(config: AxiosRequestConfig): any {
  24. return transformRequest(config.data)
  25. }
  26. function transformHeaders(config: AxiosRequestConfig): any {
  27. const { headers = {}, data } = config
  28. return processHeaders(headers, data)
  29. }
  30. function transformResponseData(res: AxiosResponse) : AxiosResponse {
  31. res.data = transformResponse(res.data)
  32. return res
  33. }
  34. export default axios

测试

./example/base/app.ts

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

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/花生_TL007/article/detail/285719
推荐阅读
相关标签
  

闽ICP备14008679号