diff --git a/README.md b/README.md index a9f0692..bd2e521 100644 --- a/README.md +++ b/README.md @@ -93,8 +93,8 @@ npm i axios-miniprogram ```typescript axios('/test', { validateStatus: function validateStatus(status) { - // 这样,状态码在 100 到 400 之间都是请求成功 - return status >= 200 && status < 300; + // 这样,状态码在 200 到 400 之间都是请求成功 + return status >= 200 && status < 400; } }); ``` @@ -130,7 +130,7 @@ axios('/test', { ##### `config.adapter`自定义平台适配器 -您可以自己适配您所在的平台 +您可以手动适配当前所处的平台 ```typescript axios.defaults.adapter = function adapter(adapterConfig) { @@ -166,7 +166,7 @@ axios.defaults.adapter = function adapter(adapterConfig) { } = adapterConfig; // 在 adapterConfig 中选择您需要的参数发送请求 - wx.request({ + return wx.request({ url, method, data, @@ -187,7 +187,7 @@ axios.defaults.adapter = wx.request; ```typescript axios.defaults.baseURL = 'https://www.xxx.com'; axios.defaults.headers.common['Accept'] = 'application/json, test/plain, */*'; -axios.defaults.headers.post['Content-Type'] = 'application/x-www-form-urlencoded'; +axios.defaults.headers.post['Content-Type'] = 'application/x-www-form-urlencoded; charset=utf-8'; ``` ##### 自定义实例默认配置 @@ -209,7 +209,7 @@ const instance = axios.create({ // 也可以创建后修改 instance.defaults.baseURL = 'https://www.xxx.com'; instance.defaults.headers.common['Accept'] = 'application/json, test/plain, */*'; -instance.defaults.headers.post['Content-Type'] = 'application/x-www-form-urlencoded'; +instance.defaults.headers.post['Content-Type'] = 'application/x-www-form-urlencoded; charset=utf-8'; ``` ##### 配置优先顺序 @@ -224,8 +224,6 @@ instance.defaults.headers.post['Content-Type'] = 'application/x-www-form-urlenco |statusText|String|状态文本|是| |data|String/Object/ArrayBuffer|开发者服务器返回的数据|是| |headers|Object|响应头|是| -|response|Object|通用响应体|是| -|request|Object|通用请求配置|是| |config|Object|Axios 请求配置|是| |cookies|Array<.String>|开发者服务器返回的 cookies,格式为字符串数组| | |profile|Object|网络请求过程中一些关键时间点的耗时信息| | diff --git a/package.json b/package.json index 292be45..5485fd7 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "axios-miniprogram", - "version": "1.0.5", + "version": "1.0.6", "description": "基于 Promise 的 HTTP 请求库,适用于各大小程序平台。", "main": "package/index.js", "miniprogram": "package", diff --git a/src/adapter/requestConfig.ts b/src/adapter/requestConfig.ts index 4966100..83abfdd 100644 --- a/src/adapter/requestConfig.ts +++ b/src/adapter/requestConfig.ts @@ -2,9 +2,10 @@ * @Author: early-autumn * @Date: 2020-04-17 15:05:43 * @LastEditors: early-autumn - * @LastEditTime: 2020-04-18 15:51:02 + * @LastEditTime: 2020-04-19 15:53:36 */ import { Method, Data, Headers, AdapterMethod, AxiosRequestConfig, RequestConfig } from '../types'; +import { pick } from '../helper/utils'; import transformURL from '../helper/transformURL'; /** @@ -24,7 +25,7 @@ function methodUppercase(config: AxiosRequestConfig): AdapterMethod { * @param config Axios 请求配置 */ export default function requestConfigOk(config: AxiosRequestConfig): RequestConfig { - const { headers, data, dataType, responseType, timeout, enableHttp2, enableQuic, enableCache, sslVerify } = config; + const { headers, data } = config; const url = transformURL(config); const method = methodUppercase(config); @@ -34,12 +35,9 @@ export default function requestConfigOk(config: AxiosRequestConfig): RequestConf header: headers as Headers, headers: headers as Headers, data: data as Data, - dataType, - responseType, - timeout, - enableHttp2, - enableQuic, - enableCache, - sslVerify, + ...pick< + AxiosRequestConfig, + 'dataType' | 'responseType' | 'timeout' | 'enableHttp2' | 'enableQuic' | 'enableCache' | 'sslVerify' + >(config, 'dataType', 'responseType', 'timeout', 'enableHttp2', 'enableQuic', 'enableCache', 'sslVerify'), }; } diff --git a/src/adapter/response.ts b/src/adapter/response.ts index 7980735..af48bfd 100644 --- a/src/adapter/response.ts +++ b/src/adapter/response.ts @@ -2,9 +2,10 @@ * @Author: early-autumn * @Date: 2020-04-17 14:09:16 * @LastEditors: early-autumn - * @LastEditTime: 2020-04-18 16:03:37 + * @LastEditTime: 2020-04-19 15:47:36 */ -import { RequestConfig, AxiosRequestConfig, AxiosResponse, Response } from '../types'; +import { AxiosRequestConfig, AxiosResponse, Response } from '../types'; +import { pick } from '../helper/utils'; /** * 各大平台通用响应体转成 Axios 响应体 @@ -15,27 +16,16 @@ import { RequestConfig, AxiosRequestConfig, AxiosResponse, Response } from '../t * @param request 通用请求配置 * @param config Axios 请求配置 */ - -export default function responseOk( - response: Response, - request: RequestConfig, - config: AxiosRequestConfig -): AxiosResponse { - response.status = response.status ?? response.statusCode; - response.headers = response.headers ?? response.header; - - const { status, headers, data, cookies, profile } = response; +export default function responseOk(response: Response, config: AxiosRequestConfig): AxiosResponse { + const status = response.status ?? response.statusCode; + const headers = response.headers ?? response.header; const statusText = status === 200 ? 'OK' : status === 400 ? 'Bad Adapter' : ''; return { status, statusText, headers, - data, - response, - request, config, - cookies, - profile, + ...pick(response, 'data', 'cookies', 'profile'), }; } diff --git a/src/core/InterceptorManager.ts b/src/core/InterceptorManager.ts index 12e9374..ad42592 100644 --- a/src/core/InterceptorManager.ts +++ b/src/core/InterceptorManager.ts @@ -2,7 +2,7 @@ * @Author: early-autumn * @Date: 2020-04-15 17:50:50 * @LastEditors: early-autumn - * @LastEditTime: 2020-04-19 02:22:28 + * @LastEditTime: 2020-04-19 13:35:47 */ import { InterceptorResolved, @@ -24,7 +24,7 @@ export default class InterceptorManagerStatic implements InterceptorManager>; + private interceptors: Record>; constructor() { this.id = 0; @@ -38,7 +38,7 @@ export default class InterceptorManagerStatic implements InterceptorManager, rejected: InterceptorRejected = (err: any) => Promise.reject(err)) { - this.interceptors[this.id++] = { + this.interceptors[++this.id] = { resolved, rejected, }; diff --git a/src/core/dispatchRequest.ts b/src/core/dispatchRequest.ts index 806fcca..2d443f3 100644 --- a/src/core/dispatchRequest.ts +++ b/src/core/dispatchRequest.ts @@ -2,7 +2,7 @@ * @Author: early-autumn * @Date: 2020-04-13 18:01:16 * @LastEditors: early-autumn - * @LastEditTime: 2020-04-18 15:53:05 + * @LastEditTime: 2020-04-19 14:52:28 */ import { AxiosRequestConfig, AxiosResponse } from '../types'; import flattenHeaders from '../helper/flattenHeaders'; diff --git a/src/helper/defaults.ts b/src/helper/defaults.ts index 0c42424..4b4057d 100644 --- a/src/helper/defaults.ts +++ b/src/helper/defaults.ts @@ -2,7 +2,7 @@ * @Author: early-autumn * @Date: 2020-04-15 22:09:38 * @LastEditors: early-autumn - * @LastEditTime: 2020-04-18 20:34:41 + * @LastEditTime: 2020-04-19 14:47:18 */ import { AxiosRequestConfig } from '../types'; import adaptive from '../adapter/adaptive'; @@ -21,10 +21,10 @@ const defaults: AxiosRequestConfig = { head: {}, delete: {}, post: { - 'Context-Type': 'application/x-www-form-urlencoded', + 'Context-Type': 'application/x-www-form-urlencoded; charset=utf-8', }, put: { - 'Context-Type': 'application/x-www-form-urlencoded', + 'Context-Type': 'application/x-www-form-urlencoded; charset=utf-8', }, }, validateStatus: function validateStatus(status) { diff --git a/src/helper/flattenHeaders.ts b/src/helper/flattenHeaders.ts index 5c84a57..77c69bd 100644 --- a/src/helper/flattenHeaders.ts +++ b/src/helper/flattenHeaders.ts @@ -2,10 +2,10 @@ * @Author: early-autumn * @Date: 2020-04-18 12:00:01 * @LastEditors: early-autumn - * @LastEditTime: 2020-04-19 02:32:15 + * @LastEditTime: 2020-04-19 15:20:17 */ import { AliasMethod, Headers, AxiosRequestConfig } from '../types'; -import { merge } from './utils'; +import { omit } from './utils'; /** * 拉平请求头 @@ -13,14 +13,17 @@ import { merge } from './utils'; * @param config Axios 请求配置 */ export default function flattenHeaders(config: AxiosRequestConfig): Headers { - let { headers = {} } = config; + const { headers } = config; + + if (headers === undefined) { + return {}; + } + const method = (config.method as string).toLowerCase() as AliasMethod; - headers = merge(headers.common ?? {}, headers[method] ?? {}, headers); - - ['common', 'options', 'delete', 'get', 'head', 'post', 'put', 'trace', 'connect'].forEach((key: string) => { - delete headers[key]; - }); - - return headers; + return { + ...(headers.common ?? {}), + ...(headers[method] ?? {}), + ...omit(headers, 'common', 'options', 'delete', 'get', 'head', 'post', 'put', 'trace', 'connect'), + }; } diff --git a/src/helper/utils.ts b/src/helper/utils.ts index fd3a3bf..812819a 100644 --- a/src/helper/utils.ts +++ b/src/helper/utils.ts @@ -2,8 +2,10 @@ * @Author: early-autumn * @Date: 2020-04-13 21:55:40 * @LastEditors: early-autumn - * @LastEditTime: 2020-04-19 01:56:21 + * @LastEditTime: 2020-04-19 16:08:40 */ +import { AnyObject } from '../types'; + const _toString = Object.prototype.toString; /** @@ -44,29 +46,6 @@ export function combineURL(baseURL: string, url: string): string { return `${baseURL.replace(/\/*$/, '')}/${url.replace(/^\/*/, '')}`; } -/** - * 浅合并多个对象 - * - * @param objs n 个对象 - */ -export function merge(...objs: Record[]): Record { - const result: Record = {}; - - function assignValue(key: string, val: any): void { - if (isPlainObject(result[key]) && isPlainObject(val)) { - result[key] = merge(result[key], val); - } else { - result[key] = val; - } - } - - objs.forEach((obj: Record): void => { - Object.entries(obj).forEach(([key, value]) => assignValue(key, value)); - }); - - return result; -} - /** * 深度合并多个对象 * @@ -102,3 +81,31 @@ export function deepMerge(...objs: Record[]): Record { return result; } + +/** + * 从对象中提取一部分属性 + * + * @param obj 源对象 + * @param keys 需要提取的 key + */ +export function pick(obj: T, ...keys: K[]): Pick { + const _pick: Partial = {}; + + keys.forEach((key: K) => (_pick[key] = obj[key])); + + return _pick as Pick; +} + +/** + * 从对象中剔除一部分属性 + * + * @param obj 源对象 + * @param keys 需要剔除的 key + */ +export function omit(obj: T, ...keys: K[]): Omit { + const _omit = { ...obj }; + + keys.forEach((key: K) => delete _omit[key]); + + return _omit; +} diff --git a/src/types.ts b/src/types.ts index dfd0a66..5df5051 100644 --- a/src/types.ts +++ b/src/types.ts @@ -2,7 +2,7 @@ * @Author: early-autumn * @Date: 2020-04-13 15:23:53 * @LastEditors: early-autumn - * @LastEditTime: 2020-04-19 02:06:24 + * @LastEditTime: 2020-04-19 14:10:56 */ /** * 任意值对象 @@ -367,16 +367,6 @@ export interface AxiosResponse { */ headers: Headers; - /** - * 通用响应体 - */ - response: Response; - - /** - * 通用请求配置 - */ - request: RequestConfig; - /** * Axios 请求配置 */ diff --git a/test/helper/buildURL.test.ts b/test/helper/buildURL.test.ts new file mode 100644 index 0000000..9b7f1cb --- /dev/null +++ b/test/helper/buildURL.test.ts @@ -0,0 +1,48 @@ +/* + * @Author: early-autumn + * @Date: 2020-04-19 14:34:13 + * @LastEditors: early-autumn + * @LastEditTime: 2020-04-19 14:40:57 + */ +import buildURL from '../../src/helper/buildURL'; + +describe('测试 /helper/buildURL.ts', () => { + it('url', () => { + expect(buildURL('/test')).toBe('/test'); + expect(buildURL('/test?id=1')).toBe('/test?id=1'); + }); + + it('url + params', () => { + expect( + buildURL('/test', { + test: 1, + }) + ).toBe('/test?test=1'); + expect( + buildURL('/test?id=1', { + test: 1, + }) + ).toBe('/test?id=1&test=1'); + }); + + it('url + params + paramsSerializer', () => { + expect( + buildURL( + '/test', + { + test: 1, + }, + () => 'paramsSerializer=ok' + ) + ).toBe('/test?paramsSerializer=ok'); + expect( + buildURL( + '/test?id=1', + { + test: 1, + }, + () => 'paramsSerializer=ok' + ) + ).toBe('/test?id=1¶msSerializer=ok'); + }); +}); diff --git a/test/helper/flattenHeaders.test.ts b/test/helper/flattenHeaders.test.ts new file mode 100644 index 0000000..2f34618 --- /dev/null +++ b/test/helper/flattenHeaders.test.ts @@ -0,0 +1,16 @@ +/* + * @Author: early-autumn + * @Date: 2020-04-19 14:43:15 + * @LastEditors: early-autumn + * @LastEditTime: 2020-04-19 16:19:24 + */ +import flattenHeaders from '../../src/helper/flattenHeaders'; + +describe('测试 src/helper/flattenHeaders.ts', () => { + it('测试 容错', () => { + expect(flattenHeaders({})).toEqual({ + Accept: 'application/json, test/plain, */*', + }); + // 'Content-Type': 'application/json; charset=utf-8', + }); +}); diff --git a/test/index.test.ts b/test/index.test.ts deleted file mode 100644 index a931e58..0000000 --- a/test/index.test.ts +++ /dev/null @@ -1,13 +0,0 @@ -/* - * @Author: early-autumn - * @Date: 2020-04-14 23:43:45 - * @LastEditors: early-autumn - * @LastEditTime: 2020-04-19 03:05:38 - */ -import { isDate } from '../src/helper/utils'; - -describe('', () => { - it('?', () => { - expect(isDate(new Date())).toBe(true); - }); -});