:::tips 简单实现一个类似axios的库 github npm :::
处理请求url参数
需求分析
参数值为数组
easyFetch({url: 'test.json',method: 'get',params: {foo: ['bar', 'baz']}})
最终的url是test.json?foo[]=bar&foo[]=baz
参数值为对象
easyFetch({url: 'test.json',method: 'get',params: {foo: {bar: 'baz'}}})
最终的url是test.json?foo=%7b22%baz,foo后面拼接的是{bar: 'baz'} encode的结果
参数值为Date类型
const date = new Date()easyFetch({url: 'test.json',method: 'get',params: {date}})
最终的url是test.json?date=2020-11-24T05...,date后面拼接的是date.toISOString()的结果
空值忽略
easyFetch({url: 'test.json',method: 'get',params: {foo: 'bar',baz: null}})
最终url是test.json?foo=bar
丢弃url中的哈希标记
easyFetch({url: 'test.json#hash',method: 'get',params: {foo: 'bar'}})
最终url是test.json?foo=bar
保存已有的参数
easyFetch({url: 'test.json?foo=bar',method: 'get',params: {bar: 'baz'}})
最终url是test.json?foo=bar&bar=baz
buildURL函数实现
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/gi, ']')}export function buildURL(url: string, params?: any): string {if(!params) return urlconst parts:string[] = []Object.keys(params).forEach(key => {const val = params[key]if(val === null || typeof val === 'undefined') returnlet values = []if(Array.isArray(val)) {values = valkey += '[]'} 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)}`)})})let serializedParams = parts.join('&')if (serializedParams) {const markIndex = url.indexOf('#')if (markIndex !== -1) {url = url.slice(0, markIndex)}url += (url.indexOf('?') === -1 ? '?' : '&') + serializedParams}return url}
处理请求body数据
XMLHttpRequest.send() 方法接受一个可选的参数,其作为请求主体;如果请求方法是 GET 或者 HEAD,则应将请求主体设置为 null — MDN
easyFetch({url: 'test.json',method: 'post',data: {a: 1,b: 2}})
如果是post请求,data是普通对象的话,需要通过JSON.stringify(data)转换成json字符串,符合XHR请求中要发送的数据体规范之一USVString 对象
处理headers
easyFetch({url: 'test.json',method: 'post',headers: {'content-type': 'application/json','Accept': 'application/json'},data: {a: 1,b: 2}})
- 如果是post请求,data是普通对象的话,用户没有定义headers,自动添加
{``'content-type': 'application/json;charset=utf-8'``} - 如果用户有定义,也要保留用户的headers
