diff --git a/docs/config/common.md b/docs/config/common.md index eefb8d4..6088ef4 100644 --- a/docs/config/common.md +++ b/docs/config/common.md @@ -117,6 +117,7 @@ export default { ::: tip * 如果想要发送二进制数据可以参阅 [FormData](../guide/form-data.md#formdata) 章节 * 如果请求头上的一些数据是异步获取到的,比如小程序端的 `cookie`。建议配置下面的 `beforeFn` 函数或是中间件,异步设置请求头。 +* 若当前以 `post` 的方式发送请求,且当前没有配置 `transformRequest` 时,`tua-api` 会自动调用 `JSON.stringify`,并设置 `Content-Type` 为 `'application/json'`。 ::: ## beforeFn 发起请求前钩子函数 diff --git a/examples/apis-web/fake-post.js b/examples/apis-web/fake-post.js index afd0985..b3dd0e1 100644 --- a/examples/apis-web/fake-post.js +++ b/examples/apis-web/fake-post.js @@ -71,5 +71,22 @@ export default { // 表示这个接口不需要传递 commonParams commonParams: null, }, + /** + * custom-transformRequest + */ + { + name: 'ct', + path: 'custom-transformRequest', + axiosOptions: { + transformRequest: () => `ct`, + }, + }, + /** + * application/json + */ + { + name: 'pj', + path: 'post-json', + }, ], } diff --git a/examples/apis-web/index.d.ts b/examples/apis-web/index.d.ts index 0bf97be..05b830f 100644 --- a/examples/apis-web/index.d.ts +++ b/examples/apis-web/index.d.ts @@ -40,7 +40,9 @@ export const fakeGetApi: { } export const fakePostApi: { + 'ct': ReqFnWithAnyParams 'oh': ReqFnWithAnyParams + 'pj': ReqFnWithAnyParams 'eap': ReqFnWithAnyParams 'hap': ReqFnWithAnyParams 'ap': ReqFn & { diff --git a/package.json b/package.json index 782f791..62d9352 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "tua-api", - "version": "1.4.4", + "version": "1.5.0", "description": "🏗 A common tool helps converting configs to api functions", "main": "dist/TuaApi.cjs.js", "module": "dist/TuaApi.esm.js", diff --git a/src/adapters/axios.js b/src/adapters/axios.js index 4fcddb2..6a51895 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, isFormData, getParamStrFromObj } from '../utils' +import { logger, isFormData, isUndefined, getParamStrFromObj } from '../utils' /** * 获取使用 axios 发起请求后的 promise 对象 @@ -11,20 +11,34 @@ export const getAxiosPromise = ({ url, data, method, - headers = DEFAULT_HEADER, + headers, crossDomain = true, withCredentials = true, - transformRequest = [getParamStrFromObj], + transformRequest, ...rest }) => { const isFD = isFormData(data) + const isPost = method.toLowerCase() === 'post' logger.log(`Req Url: ${url}`) if (data && (Object.keys(data).length || isFD)) { logger.log('Req Data:', data) } - transformRequest = isFD ? null : transformRequest + // 优先使用用户的配置 + if (isUndefined(transformRequest)) { + transformRequest = isFD + ? null + : isPost + // 如果使用 post 的请求方式,自动对其 stringify + ? x => JSON.stringify(x) + : getParamStrFromObj + } + if (isUndefined(headers)) { + headers = isPost + ? { 'Content-Type': 'application/json;charset=utf-8' } + : DEFAULT_HEADER + } return axios({ url, diff --git a/src/constants.js b/src/constants.js index 9cf3716..e690976 100644 --- a/src/constants.js +++ b/src/constants.js @@ -5,7 +5,7 @@ const VALID_REQ_TYPES = ['wx', 'axios', 'jsonp'] const WX_VALID_METHODS = ['OPTIONS', 'GET', 'HEAD', 'POST', 'PUT', 'DELETE', 'TRACE', 'CONNECT'] // 默认请求头 -const DEFAULT_HEADER = { 'Content-Type': 'application/x-www-form-urlencoded' } +const DEFAULT_HEADER = { 'Content-Type': 'application/x-www-form-urlencoded;charset=utf-8' } // 错误信息 const ERROR_STRINGS = { diff --git a/src/utils/judge.js b/src/utils/judge.js index ba9f021..0274f58 100644 --- a/src/utils/judge.js +++ b/src/utils/judge.js @@ -7,3 +7,5 @@ export const isFormData = (val) => ( (typeof FormData !== 'undefined') && (val instanceof FormData) ) + +export const isUndefined = val => typeof val === 'undefined' diff --git a/test/__tests__/axios.test.js b/test/__tests__/axios.test.js index 693b254..e8fc981 100644 --- a/test/__tests__/axios.test.js +++ b/test/__tests__/axios.test.js @@ -1,6 +1,7 @@ import axios from 'axios' import MockAdapter from 'axios-mock-adapter' +import fakePostConfig from '@examples/apis-web/fake-post' import { ERROR_STRINGS } from '@/constants' import { fakeGetApi, fakePostApi } from '@examples/apis-web/' @@ -19,6 +20,8 @@ const reqTAUrl = 'http://example-base.com/fake-get/req-type-axios?asyncCp=asyncC const reqEAPUrl = 'http://example-base.com/fake-post/empty-array-params' const reqMFDUrl = 'http://example-base.com/fake-get/mock-function-data' const reqBFCUrl = 'http://example-base.com/fake-get/beforeFn-cookie' +const reqCTUrl = 'http://example-base.com/fake-post/custom-transformRequest' +const reqPjUrl = 'http://example-base.com/fake-post/post-json' describe('middleware', () => { test('change baseUrl before request', async () => { @@ -164,4 +167,27 @@ describe('fake post requests', () => { expect(data).toBe(formData) expect(transformRequest).toBe(null) }) + + test('custom-transformRequest', async () => { + mock.resetHistory() + mock.onPost(reqCTUrl).reply(200, {}) + + await fakePostApi.ct() + + const { data } = mock.history.post[0] + + expect(data).toBe('ct') + }) + + test('post-json', async () => { + mock.resetHistory() + mock.onPost(reqPjUrl).reply(200, {}) + + await fakePostApi.pj() + + const { data } = mock.history.post[0] + + expect(data).toBe(JSON.stringify(fakePostConfig.commonParams)) + expect(mock.history.post[0].headers['Content-Type']).toBe('application/json;charset=utf-8') + }) })