Axios对get参数的处理

5,319 阅读2分钟

axios中对各种类型参数的处理。

1. 字符串/数字-(错误的)

在官方文档中有这样的一段话

// 必须是一个无格式对象(plain object,对象字面量或使用object.create()创建)或 URLSearchParams 对象 params: { ID: 12345 },

所以我们需要使用对象格式传参。

但是笔者验证过

axios({
  baseURL:"http://localhost:4396",
  method: 'get',
  url: '/api/test/get',
  params: 1
})

get参数-字符串.png

2. 普通参数

axios({
  baseURL:"http://localhost:4396",
  method: 'get',
  url: '/api/test/get',
  params: {
    a: 1,
    b: 2
  }
})

object.png

3. URLSearchParams

 axios({
     baseURL: "http://localhost:4396",
     method: "get",
     url: "/api/test/get",
     params: new URLSearchParams('?a=1')
 });

get-urlsearchparams.png

4 数组

   axios({
        baseURL: "http://localhost:4396",
        method: "get",
        url: "/api/test/get",
        params: {
          a: [1, 2],
        },
      });

get-数组.png

5. object -> JSON.stringify

axios({
    baseURL: "http://localhost:4396",
    method: "get",
    url: "/api/test/get",
    params: {
        a: {
            b: "1",
        },
    },
});

get-object.png

6. date ->toISOString()

axios({
    baseURL: "http://localhost:4396",
    method: "get",
    url: "/api/test/get",
    params: {
        a:new Date(),
    },
});

date.png

7. 特殊字符

axios({
    baseURL: "http://localhost:4396",
    method: "get",
    url: "/api/test/get",
    params: {
        foo: "@:$, []",
    },
});

特殊字符.png

8. null / undefined -> 直接忽略

axios({
    baseURL: "http://localhost:4396",
    method: "get",
    url: "/api/test/get",
    params: {
        a: "1",
        b: null,
    },
});

null.png

9. 存在hash# -> 去掉hash

 axios({
     baseURL: "http://localhost:4396",
     method: "get",
     url: "/api/test/get#hash?a=1",
     params: {
         b: "2",
     },
 });

hash.png

10 url中存在参数

 // url 中已存在参数
      axios({
        baseURL: "http://localhost:4396",
        method: "get",
        url: "/api/test/get?a=1",
        params: {
          b: "2",
        },
      });

已有参数.png

实现

  1. buildURL.ts
import { isDate, isObject,isURLSearchParams } from './../util/index'
function encode(val: string): string {
    // 这里的%40 是后面字符的十六进制的转义序列
    return encodeURIComponent(val)
        .replace(/%40/g, '@')
        .replace(/%3A/gi, ':')
        .replace(/%24/g, '$')
        .replace(/%2C/gi, ',')
        .replace(/%20/g, '+')
        .replace(/%5B/gi, '[')
        .replace(/%5D/gi, ']')
}
export default function buildURL(url: string, params: any): string {

    // 如果不存在params参数,直接返回
    if (!params) {
        return url
    }
    if(isURLSearchParams(params)){
      return   url += (url.includes('?') ? '&' : '?') + params.toString()
    }
    const parts: string[] = []
    console.log(params)
    // 对所有参数进行遍历
    // 例子
    // params: {
    //     a: [1, 2, 3, 34],
    //     b: {c:1},
    //     d:new Date()
    //   },
    Object.keys(params).forEach((key: string) => {
        const val: any = params[key]
        // 如果值是null或者undefined直接跳过
        if (val === null || typeof val === 'undefined') {
            return
        }
        let tempVal: string[] = []
        // 如果当前参数是数组,例如a
        if (Array.isArray(val)) {
            tempVal = val
            // 数组变成a[]=1&a[]=2&a[]=3&a[]=34,所以要在key后面加上[ ]
            key = key + '[]'

        } else {
            // 如果不是数组变成数组,这里变成数组,是为了共用下面的foreach
            // 当然也可以不变成数组,但是下面就要对tempVal的类型进行判断
            tempVal = [val]
        }
        tempVal.forEach((temp: any) => {
            if (isDate(temp)) {
                temp = val.toISOString();
            } else if (isObject(temp)) {
                temp = JSON.stringify(temp)
            }
            // 利用encodeURIComponent变成 URI 格式
            parts.push(`${encode(key)}=${encode(temp)}`)

        })

    })
    // 判断url中是否有# 
    const hashmarkIndex:number = url.indexOf('#');
    if (hashmarkIndex !== -1) {
      url = url.slice(0, hashmarkIndex);
    }
    // 判断url有没有已经存在参数 /api/test/get?a=1,如果存在 使用&
    url += (url.includes('?') ? '&' : '?') + parts
    console.log(url)
    return url
}
  1. 辅助函数 src\util\index.ts
export function isDate(val: any): boolean {
    return toString.call(val) === '[object Date]';
}

export function isObject(val: any): boolean {
    return val !== null && typeof val === 'object';
}

export function isURLSearchParams(val:any): boolean {
    return typeof URLSearchParams !== 'undefined' && val instanceof URLSearchParams;
}