美文网首页
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