美文网首页
2-3、处理请求header

2-3、处理请求header

作者: Eileen_1d88 | 来源:发表于2019-12-04 22:45 被阅读0次

处理request body遗留的问题

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

我们做了请求数据的处理,把data转换成了json字符串,但是服务端并不能正确解析出我们发送的数据。这是因为我们没有在header中设置正确的Content-Type,所以我们需要在发送请求的时候,支持配置headers属性,如下:

axios({
  method: 'post',
  url: '/base/post',
  headers: {
    'content-type': 'application/json;charset=utf-8'
  },
  data: {
    a: 1,
    b: 2
  }
})

并且在传入普通json对象并且没有设置Content-Type时,默认Content-Type: 'application/json;charset=utf-8'
那么接下来我们来实现processHeaders函数
src/helpers/headers

import { isPlainObject } from "./util";

function normalizeHeaderName(headers: any, normalizedName: string): void {
  if (!headers) {
    return
  }
  Object.keys(headers).forEach(name => {
    if (name.toLowerCase() === normalizedName.toLowerCase() && name !== normalizedName) {
      headers[normalizedName] = headers[name]
      delete headers[name]
    }
  })
}

function processHeaders(headers: any, data: any): any {
  // 因为headers中的属性名是大小写不敏感的,所以我们需要对headers中的属性规范化
  normalizeHeaderName(headers, 'Content-Type')
  // 如果data为空,那么设置'Content-Type'是没有意义的,这里删除它
  if (!data) {
    if (headers && headers['Content-Type']) {
      delete headers['Content-Type']
    }
    return headers
  }
  if (isPlainObject(data)) {
    if (!headers) {
      headers = {
        'Content-Type': 'application/json;charset=utf-8'
      }
      return headers
    }
    if (!headers['Content-Type']) {
      headers['Content-Type'] = 'application/json;charset=utf-8'
    }
  }
  return headers
}

export {
  processHeaders
}

src/index.ts

import { AxiosRequestConfig } from "./types";
import xhr from './xhr'
import { buildUrl } from "./helpers/url";
import { transformRequest } from "./helpers/data";
import { processHeaders } from "./helpers/headers";

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

function processConfig(config: AxiosRequestConfig): void {
  config.url = tranformUrl(config)
  config.headers = transformHeaders(config)
  config.data = transformRequestData(config)
}

function tranformUrl(config: AxiosRequestConfig): string {
  const { url, params } = config
  return buildUrl(url, params)
}

function transformRequestData(config: AxiosRequestConfig): any {
  return transformRequest(config.data)
}

function transformHeaders(config: AxiosRequestConfig): any {
  const { headers = {}, data } = config
  return processHeaders(headers, data)
}

src/xhr.ts

import { AxiosRequestConfig } from "./types";

export default function xhr(config: AxiosRequestConfig): void {
  // method和data可能没有, 所以给出默认值
  const { url, method = 'get', data = null, headers } = config
  const request = new XMLHttpRequest()
  request.open(method.toUpperCase(), url)
  Object.keys(headers).forEach((name) => {
    request.setRequestHeader(name, headers[name])
  })
  request.send(data)
}

编写demo

import axios from '../../src/index'
axios({
  method: 'post',
  url: '/api/base/post',
  data: {
    a: 1,
    b: 2
  }
})

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

axios({
  method: 'post',
  url: '/api/base/post',
  headers: {
    'content-type': 'application/json;'
  },
  data: {
    a: 1,
    b: 2
  }
})

const paramsString = 'q=URLUtils.searchParams&topic=api'
const searchParams = new URLSearchParams(paramsString)

axios({
  method: 'post',
  url: '/api/base/post',
  data: searchParams
})

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

axios({
  method: 'post',
  url: '/api/base/buffer',
  data: arr
})

通过 demo 我们可以看到,当我们请求的数据是普通对象并且没有配置 headers 的时候,会自动为其添加 Content-Type:application/json;charset=utf-8;同时我们发现当 data 是某些类型如 URLSearchParams 的时候,浏览器会自动为请求 header加上合适的 Content-Type。

至此我们对于请求的处理逻辑暂时告一段落。目前我们的请求从网络层面是可以收到服务端的响应的,下一节课我们就从代码层面来处理服务端响应,并且让调用方可以拿到从服务端返回的数据。

相关文章

网友评论

      本文标题:2-3、处理请求header

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