From a6696625c0fe3a3f9ad2f2d534360deed37e2b63 Mon Sep 17 00:00:00 2001 From: StEve Young <2747745470@qq.com> Date: Tue, 23 Apr 2019 19:44:10 +0800 Subject: [PATCH] feat(axios): close #32, support FormData type params (#35) --- .eslintrc.js | 1 + docs/.vuepress/config.js | 1 + docs/config/common.md | 2 +- docs/config/default.md | 2 +- docs/guide/form-data.md | 28 ++++++++++++++++++++++++++++ package.json | 3 ++- src/adapters/axios.js | 8 ++++++-- src/middlewareFns.js | 7 +++++++ src/utils/env.js | 4 ---- src/utils/index.js | 2 +- src/utils/judge.js | 9 +++++++++ test/.eslintrc.js | 5 ++++- test/__tests__/axios.test.js | 21 +++++++++++++++++++++ 13 files changed, 82 insertions(+), 11 deletions(-) create mode 100644 docs/guide/form-data.md delete mode 100644 src/utils/env.js create mode 100644 src/utils/judge.js diff --git a/.eslintrc.js b/.eslintrc.js index 8052a3b..79589e0 100644 --- a/.eslintrc.js +++ b/.eslintrc.js @@ -8,5 +8,6 @@ module.exports = { }, globals: { wx: true, + FormData: true, }, } diff --git a/docs/.vuepress/config.js b/docs/.vuepress/config.js index 4e502a1..44a26a4 100644 --- a/docs/.vuepress/config.js +++ b/docs/.vuepress/config.js @@ -47,6 +47,7 @@ module.exports = { 'middleware', 'mock', 'export-utils', + 'form-data', '../config/', ], }, diff --git a/docs/config/common.md b/docs/config/common.md index 8626f42..d004cb7 100644 --- a/docs/config/common.md +++ b/docs/config/common.md @@ -49,7 +49,7 @@ export default { ``` ## reqType 请求使用库类型 -即用哪个库发起请求目前支持:jsonp、axios,不填则使用默认配置。 +即用哪个库发起请求目前支持:jsonp、axios、wx,不填则使用默认配置中的 reqType。 ```js export default { diff --git a/docs/config/default.md b/docs/config/default.md index 82e48ac..e090ed7 100644 --- a/docs/config/default.md +++ b/docs/config/default.md @@ -18,7 +18,7 @@ new TuaApi({ 例如 `https://example.com/api/` ## reqType 请求类型 -即在 web 端使用哪个库发起请求目前支持:jsonp、axios,不填默认使用 axios。(小程序端没得选...) +即使用哪个库发起请求目前支持:jsonp、axios、wx,不填默认使用 axios。 ## middleware 中间件函数数组 【所有】请求都会调用的中间件函数数组!适合添加一些通用逻辑,例如接口上报。 diff --git a/docs/guide/form-data.md b/docs/guide/form-data.md new file mode 100644 index 0000000..8e26e79 --- /dev/null +++ b/docs/guide/form-data.md @@ -0,0 +1,28 @@ +# FormData +## 发送二进制数据 +日常使用中,除了简单的字符串参数以外,有时也会遇到需要发送二进制数据的场景,例如上传文件。 + +在旧版的 `tua-api` 中若是遇到这种请求,也能发送但比较繁琐。 + +```js +const formData = new FormData() + +imgUploadApi.userUpload(null, { + reqFnParams: { reqParams: formData }, + axiosOptions: { transformRequest: null }, +}) +``` + +如上例所示,借助第二个参数[运行时配置](../config/runtime.md)设置了:数据、 `transformRequest`。 + +而在新版本的 `tua-api` 中,只要这么调用即可: + +```js +const formData = new FormData() + +imgUploadApi.userUpload(formData) +``` + +实现原理是 `tua-api` 在底层判断出接收的接口参数是 `FormData` 类型的数据,自动设置了 `transformRequest`。 + +> 小程序端暂时建议使用原生的 `wx.uploadFile`。 diff --git a/package.json b/package.json index 6f91fc8..fb1286c 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "tua-api", - "version": "1.2.1", + "version": "1.3.0", "description": "🏗 A common tool helps converting configs to api functions", "main": "dist/TuaApi.cjs.js", "module": "dist/TuaApi.esm.js", @@ -58,6 +58,7 @@ }, "eslintIgnore": [ "dist/*", + "!.eslintrc.js", "package.json" ], "dependencies": { diff --git a/src/adapters/axios.js b/src/adapters/axios.js index f6810d9..2db9852 100644 --- a/src/adapters/axios.js +++ b/src/adapters/axios.js @@ -1,7 +1,7 @@ import axios from 'axios' import { DEFAULT_HEADER } from '../constants' -import { logger, getParamStrFromObj } from '../utils' +import { logger, isFormData, getParamStrFromObj } from '../utils' // 获取使用 axios 发起请求后的 promise 对象 export const getAxiosPromise = ({ @@ -14,11 +14,15 @@ export const getAxiosPromise = ({ transformRequest = [getParamStrFromObj], ...rest }) => { + const isFD = isFormData(data) + logger.log(`Req Url: ${url}`) - if (data && Object.keys(data).length) { + if (data && (Object.keys(data).length || isFD)) { logger.log(`Req Data:`, data) } + transformRequest = isFD ? null : transformRequest + return axios({ url, data, diff --git a/src/middlewareFns.js b/src/middlewareFns.js index 057b0a9..fd5eb16 100644 --- a/src/middlewareFns.js +++ b/src/middlewareFns.js @@ -1,5 +1,6 @@ import { ERROR_STRINGS } from './constants' import { + isFormData, checkArrayParams, getParamStrFromObj, getDefaultParamObj, @@ -64,6 +65,12 @@ const formatReqParamsMiddleware = (ctx, next) => { throw TypeError(ERROR_STRINGS.argsType) } + if (isFormData(args)) { + ctx.req.reqParams = args + + return next() + } + checkArrayParams(ctx.req) // 根据配置生成请求的参数 diff --git a/src/utils/env.js b/src/utils/env.js deleted file mode 100644 index 6a1ad39..0000000 --- a/src/utils/env.js +++ /dev/null @@ -1,4 +0,0 @@ -export const isWx = () => ( - typeof wx !== 'undefined' && - typeof wx.request === 'function' -) diff --git a/src/utils/index.js b/src/utils/index.js index 3150cc7..31aefa7 100644 --- a/src/utils/index.js +++ b/src/utils/index.js @@ -1,5 +1,5 @@ export * from './fp' export * from './mp' -export * from './env' +export * from './judge' export * from './logger' export * from './params' diff --git a/src/utils/judge.js b/src/utils/judge.js new file mode 100644 index 0000000..ba9f021 --- /dev/null +++ b/src/utils/judge.js @@ -0,0 +1,9 @@ +export const isWx = () => ( + typeof wx !== 'undefined' && + typeof wx.request === 'function' +) + +export const isFormData = (val) => ( + (typeof FormData !== 'undefined') && + (val instanceof FormData) +) diff --git a/test/.eslintrc.js b/test/.eslintrc.js index 64a76a5..ec25184 100644 --- a/test/.eslintrc.js +++ b/test/.eslintrc.js @@ -1,3 +1,6 @@ module.exports = { - env: { jest: true } + env: { jest: true }, + globals: { + FormData: true, + }, } diff --git a/test/__tests__/axios.test.js b/test/__tests__/axios.test.js index 3b1b641..8c8a7fc 100644 --- a/test/__tests__/axios.test.js +++ b/test/__tests__/axios.test.js @@ -92,6 +92,10 @@ describe('fake get requests', () => { }) describe('fake post requests', () => { + beforeEach(() => { + mock.resetHistory() + }) + test('own-host', async () => { const data = { code: 0, data: 'own-host' } mock.onPost(reqOHUrl).reply(200, data) @@ -123,4 +127,21 @@ describe('fake post requests', () => { expect(resData).toEqual({ code: 0, data: 'array data' }) }) + + test('form-data', async () => { + mock.onPost(reqOHUrl).reply(200, {}) + const formData = new FormData() + formData.append('a', 'a') + formData.append('b', 123) + + await fakePostApi.oh(formData) + + const { + data, + transformRequest, + } = mock.history.post[0] + + expect(data).toBe(formData) + expect(transformRequest[0].name).toBe('transformRequest') + }) })