编写基础请求代码中最后的测试demo是
import axios from '../../src/index'
axios({
url: '/api/demo1/get',
params: {
a: 1,
b: 2
}
})
我们希望最后请求的url是/api/demo1/get?a=1&b=2,这样服务端就可以通过请求的url解析到我们传来的参数数据了。实际上就是把params对象的key和value拼接到url上。
以下是一些参数类型,以及最后我们希望得到的结果的例子
- 参数值为数组
axios({
method: 'get',
url: '/api/demo1/get',
params: {
foo: ['bar', 'baz']
}
})
最终希望的url是/api/demo1/get?foo[]=bar&foo[]=baz
- 参数值为对象
axios({
method: 'get',
url: '/api/demo1/get',
params: {
foo: {
bar: 'baz'
}
}
})
最终希望的url是/api/demo1/get?foo=%7B%22bar%22:%22baz%22%7D, foo后面拼接的是{bar: 'baz'}encode后的结果
- 参数值为Date类型
const date = new Date()
axios({
method: 'get',
url: '/api/demo1/get',
params: {
date
}
})
最终希望的url是/api/demo1/get?date=2019-04-01T05:55:39.030Z, date后面拼接的是date.toISOString()的结果。
- 特殊字符支持
对于字符@、:、$、,、、[、],我们是允许出现在 url 中的,不希望被 encode。
axios({
method: 'get',
url: '/api/demo1/get',
params: {
foo: '@:$, '
}
})
最终请求的 url 是 /api/demo1/get?foo=@:$+,注意,我们会把空格 转换成 +。
- 空值忽略
对于值为null或者undefined的属性,我们是不会添加到url参数中的
axios({
method: 'get',
url: '/api/demo1/get',
params: {
foo: 'bar',
baz: null
}
})
最终请求的 url 是 /api/demo1/get?foo=bar
- 丢掉url中的哈希标记
axios({
method: 'get',
url: '/api/demo1/get#hash',
params: {
foo: 'bar'
}
})
最终请求的 url是 /api/demo1/get?foo=bar
- 保留url中已存在的参数
axios({
method: 'get',
url: '/api/demo1/get?foo=bar',
params: {
bar: 'baz'
}
})
最终请求的url是/base/get?foo=bar&bar=baz
根据以上的需求,我们来实现一个buildUrl的函数
src/helpers/url.ts
import { isDate, isObject } from "./util"
function encode(val: string): string {
return encodeURIComponent(val)
.replace(/%40/g, '@')
.replace(/%3A/gi, ':')
.replace(/%24/g, '$')
.replace(/%2C/gi, ',')
.replace(/%20/g, '+')
.replace(/%5B/gi, '[')
.replace(/%5D/g, ']')
}
function buildUrl(url: string, params?: any) {
// 去掉哈希符号
const hashIndex = url.indexOf('#')
if (hashIndex !== -1) {
url = url.slice(0, hashIndex)
}
if (!params) {
return url
}
const parts: string[] = []
Object.keys(params).forEach(key => {
let val = params[key]
if (val === null || val === 'undefined') {
return
}
let values: string[]
if (Array.isArray(val)) {
values = val
key += '[]'
} else {
values = [val]
}
values.forEach(val => {
if (isDate(val)) {
val = val.toISOString()
} else if (isObject(val)){
val = JSON.stringify(val)
}
parts.push(`${encode(key)}=${encode(val)}`)
})
})
const serializedParams = parts.join('&')
url += (url.indexOf('?') === -1 ? '?' : '&') + serializedParams
return url
}
export {
buildUrl
}
src/helpers/util.ts
const toString = Object.prototype.toString
function isDate(val: any): val is Date {
return toString.call(val) === '[object Date]'
}
function isObject(val: any): val is Object {
return val !== null && typeof val === 'object'
}
export {
isDate,
isObject
}
src/index.ts
import { AxiosRequestConfig } from "./types";
import xhr from './xhr'
import { buildUrl } from "./helpers/url";
export default function axios(config: AxiosRequestConfig) {
processConfig(config)
xhr(config)
}
function processConfig(config: AxiosRequestConfig): void {
config.url = tranformUrl(config)
}
function tranformUrl(config: AxiosRequestConfig): string {
const { url, params } = config
return buildUrl(url, params)
}
编写demo
import axios from '../../src/index'
axios({
url: '/api/demo1/get',
params: {
a: 1,
b: 2
}
})
axios({
url: '/api/demo1/get#test',
params: {
a: 1,
b: 2
}
})
axios({
url: '/api/demo1/get#test'
})
axios({
url: '/api/demo1/get',
params: {
foo: ['bar', 'baz']
}
})
axios({
method: 'get',
url: '/api/demo1/get',
params: {
foo: {
bar: 'baz'
}
}
})
axios({
method: 'get',
url: '/api/demo1/get',
params: {
foo: '@:$, '
}
})
axios({
method: 'get',
url: '/api/demo1/get',
params: {
foo: 'bar',
baz: null
}
})
axios({
method: 'get',
url: '/api/demo1/get#hash',
params: {
foo: 'bar'
}
})
axios({
method: 'get',
url: '/api/demo1/get?foo=bar',
params: {
bar: 'baz'
}
})
const date = new Date()
axios({
method: 'get',
url: '/api/demo1/get',
params: {
date
}
})
那么我们对于url的处理就完成了,接下来我们来处理request body










网友评论