Skip to content

Commit

Permalink
fix(jsonp): do not set default callbackName, set default charset (#45)
Browse files Browse the repository at this point in the history
  • Loading branch information
BuptStEve authored Feb 17, 2020
1 parent d867b9c commit 1f379af
Show file tree
Hide file tree
Showing 10 changed files with 110 additions and 49 deletions.
30 changes: 28 additions & 2 deletions docs/config/runtime.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,16 +10,42 @@ exampleApi.foo(
)
```

## callback 回调函数参数的名称 <Badge text="1.4.4+"/>
通过 jsonp 发起请求时,在请求的 `url` 上都会有一个参数用来标识回调函数,例如 `callback=jsonp_1581908021389_16566`

`callback` 这个参数可以用来标识等号左边的值(不填则默认为 `callback`)。

```js
exampleApi.foo(
{ ... },
{ callback: `cb` }
)
```

最终的请求 `url` 大概是:`/foo?cb=jsonp_1581908021389_16566`

::: tip
`callback` 其实就是透传了 `fetch-jsonp` 中的 `jsonpCallback`
:::

## callbackName 回调函数名称
在通过 jsonp 发起请求时,为了使用缓存一般需要添加 callbackName,但是注意重复请求时会报错。
通过 jsonp 发起请求时,一般默认回调函数的名称都是由一些随机值构成,例如 `callback=jsonp_1581908021389_16566`

不过为了使用缓存一般需要添加 `callbackName`,但是注意重复请求时会报错(此时不设置 `callbackName` 即可)。

```js
exampleApi.foo(
{ ... },
{ callbackName: `foo` }
{ callbackName: `fooCallback` }
)
```

最终的请求 `url` 大概是:`/foo?callback=fooCallback`

::: tip
`callbackName` 其实就是透传了 `fetch-jsonp` 中的 `jsonpCallbackFunction`
:::

## 其他参数
公共配置一节中的所有参数(除了 `pathList` 外),以及自身配置一节中的所有参数均有效,且优先级最高。

Expand Down
13 changes: 12 additions & 1 deletion examples/apis-web/fake-get.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,11 @@ export default {
commonParams: null,

// 透传 `fetch-jsonp` 需要配置的参数。例如需要传递超时时间时可添加:
jsonpOptions: { timeout: 10 * 1000 },
jsonpOptions: {
timeout: 10 * 1000,
jsonpCallback: 'cb',
jsonpCallbackFunction: 'cbName',
},

// 透传 `axios` 需要配置的参数。例如需要传递超时时间时可添加:
axiosOptions: { timeout: 10 * 1000 },
Expand Down Expand Up @@ -154,5 +158,12 @@ export default {
/** @type { import('../../src/').ReqType } */
reqType: ('axios'),
},
/**
* jsonp-options
*/
{
name: 'jsonpOptions',
path: 'jsonp-options',
},
],
}
1 change: 1 addition & 0 deletions examples/apis-web/index.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ export const fakeGetApi: {
'afterData': ReqFnWithAnyParams
'mockFnData': ReqFnWithAnyParams
'noAfterData': ReqFnWithAnyParams
'jsonpOptions': ReqFnWithAnyParams
'beforeFnCookie': ReqFnWithAnyParams
'mockObjectData': ReqFnWithAnyParams
'empty-array-params': ReqFnWithAnyParams
Expand Down
55 changes: 27 additions & 28 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "tua-api",
"version": "1.4.3",
"version": "1.4.4",
"description": "🏗 A common tool helps converting configs to api functions",
"main": "dist/TuaApi.cjs.js",
"module": "dist/TuaApi.esm.js",
Expand Down Expand Up @@ -36,8 +36,7 @@
},
"lint-staged": {
"{src,test}/**/*.js": [
"eslint --fix",
"git add"
"eslint --fix"
]
},
"eslintIgnore": [
Expand All @@ -46,47 +45,47 @@
"package.json"
],
"dependencies": {
"axios": "^0.19.0",
"axios": "^0.19.2",
"fetch-jsonp": "^1.1.3",
"koa-compose": "^4.1.0"
},
"devDependencies": {
"@babel/core": "^7.6.4",
"@babel/plugin-external-helpers": "^7.2.0",
"@babel/plugin-proposal-decorators": "^7.6.0",
"@babel/plugin-proposal-object-rest-spread": "^7.6.2",
"@babel/preset-env": "^7.6.3",
"@commitlint/cli": "^8.2.0",
"@commitlint/config-conventional": "^8.2.0",
"@types/jest": "^24.0.18",
"all-contributors-cli": "^6.9.1",
"@babel/core": "^7.8.4",
"@babel/plugin-external-helpers": "^7.8.3",
"@babel/plugin-proposal-decorators": "^7.8.3",
"@babel/plugin-proposal-object-rest-spread": "^7.8.3",
"@babel/preset-env": "^7.8.4",
"@commitlint/cli": "^8.3.5",
"@commitlint/config-conventional": "^8.3.4",
"@types/jest": "^25.1.2",
"all-contributors-cli": "^6.13.0",
"axios-mock-adapter": "^1.17.0",
"babel-core": "^7.0.0-bridge.0",
"babel-eslint": "^10.0.3",
"babel-jest": "^24.9.0",
"codecov": "^3.6.1",
"cross-env": "^6.0.3",
"eslint": "^6.5.1",
"babel-jest": "^25.1.0",
"codecov": "^3.6.5",
"cross-env": "^7.0.0",
"eslint": "^6.8.0",
"eslint-config-standard": "^14.1.0",
"eslint-plugin-import": "^2.18.2",
"eslint-plugin-node": "^10.0.0",
"eslint-plugin-import": "^2.20.1",
"eslint-plugin-node": "^11.0.0",
"eslint-plugin-promise": "^4.2.1",
"eslint-plugin-standard": "^4.0.1",
"gh-pages": "^2.1.1",
"husky": "^3.0.8",
"jest": "^24.9.0",
"lint-staged": "^9.4.2",
"rimraf": "^3.0.0",
"rollup": "^1.23.1",
"gh-pages": "^2.2.0",
"husky": "^4.2.3",
"jest": "^25.1.0",
"lint-staged": "^10.0.7",
"rimraf": "^3.0.2",
"rollup": "^1.31.1",
"rollup-plugin-babel": "^4.3.3",
"rollup-plugin-commonjs": "^10.1.0",
"rollup-plugin-eslint": "^7.0.0",
"rollup-plugin-json": "^4.0.0",
"rollup-plugin-node-resolve": "^5.2.0",
"rollup-plugin-replace": "^2.2.0",
"rollup-plugin-uglify": "^6.0.3",
"typescript": "^3.6.4",
"vuepress": "^1.1.0"
"rollup-plugin-uglify": "^6.0.4",
"typescript": "^3.7.5",
"vuepress": "^1.3.0"
},
"repository": {
"type": "git",
Expand Down
4 changes: 2 additions & 2 deletions src/exportUtils.js
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ const getSyncFnMapByApis = pipe(
map(values),
flatten,
map(val => ({ [val.key]: val })),
mergeAll
mergeAll,
)

/**
Expand All @@ -53,7 +53,7 @@ const getPreFetchFnKeysBySyncFnMap = (syncFnMap) => pipe(

return Object.keys(params).every(isParamNotRequired)
}),
map(key => ({ key }))
map(key => ({ key })),
)(syncFnMap)

export {
Expand Down
24 changes: 13 additions & 11 deletions src/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ class TuaApi {
if (host) {
logger.warn(
'[host] will be deprecated, please use [baseUrl] instead!\n' +
'[host] 属性将被废弃, 请用 [baseUrl] 替代!'
'[host] 属性将被废弃, 请用 [baseUrl] 替代!',
)
}

Expand Down Expand Up @@ -109,6 +109,7 @@ class TuaApi {
* @param {string} options.reqType 使用什么工具发(axios/jsonp/wx)
* @param {object} options.reqParams 请求参数
* @param {object} options.header 请求的 header
* @param {string} options.callback 使用 jsonp 时标识回调函数的名称
* @param {string} options.callbackName 使用 jsonp 时的回调函数名
* @param {object} options.axiosOptions 透传 axios 配置参数
* @param {object} options.jsonpOptions 透传 fetch-jsonp 配置参数
Expand All @@ -122,7 +123,8 @@ class TuaApi {
fullUrl,
reqType,
reqParams: data,
callbackName: jsonpCallbackFunction,
callback,
callbackName,
axiosOptions,
jsonpOptions,
...rest
Expand Down Expand Up @@ -157,10 +159,13 @@ class TuaApi {
return getAxiosPromise(params)
}

return getFetchJsonpPromise({
url: fullUrl,
jsonpOptions: { ...jsonpOptions, jsonpCallbackFunction },
})
// 防止接口返回非英文时报错
jsonpOptions.charset = jsonpOptions.charset || 'UTF-8'

jsonpOptions.jsonpCallback = callback || jsonpOptions.jsonpCallback
jsonpOptions.jsonpCallbackFunction = callbackName || jsonpOptions.jsonpCallbackFunction

return getFetchJsonpPromise({ url: fullUrl, jsonpOptions })
}

/**
Expand Down Expand Up @@ -245,7 +250,7 @@ class TuaApi {
if (type) {
logger.warn(
'[type] will be deprecated, please use [method] instead!\n' +
'[type] 属性将被废弃, 请用 [method] 替代!'
'[type] 属性将被废弃, 请用 [method] 替代!',
)
}

Expand Down Expand Up @@ -293,9 +298,6 @@ class TuaApi {

runtimeParams.method = runtimeParams.method || runtimeParams.type

// 自定义回调函数名称(用于 jsonp)
runtimeParams.callbackName = runtimeParams.callbackName || `${runtimeParams.path}Callback`

// 请求的上下文信息
const ctx = {
req: { args, mock: apiFn.mock, reqFnParams: {}, ...runtimeParams },
Expand Down Expand Up @@ -326,7 +328,7 @@ class TuaApi {
.then(() => afterFn([ctx.res.data, ctx]))
.then((data) => ctx.res.error
? Promise.reject(ctx.res.error)
: data || ctx.res.data
: data || ctx.res.data,
)
}

Expand Down
4 changes: 2 additions & 2 deletions src/utils/fp.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ const map = (fn) => (arr) => Array.isArray(arr)
: pipe(
Object.keys,
map(key => ({ [key]: fn(arr[key]) })),
mergeAll
mergeAll,
)(arr)

const join = str => arr => arr.join(str)
Expand All @@ -20,7 +20,7 @@ const flatten = reduce(
(acc, cur) => Array.isArray(cur)
? compose(concat, flatten)(cur)(acc)
: concat(cur)(acc),
[]
[],
)

const merge = (acc, cur) => ({ ...acc, ...cur })
Expand Down
4 changes: 2 additions & 2 deletions src/utils/params.js
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ import { ERROR_STRINGS } from '../constants'
const getParamStrFromObj = (data = {}) => pipe(
Object.keys,
map(key => `${encodeURIComponent(key)}=${encodeURIComponent(data[key])}`),
join('&')
join('&'),
)(data)

/**
Expand Down Expand Up @@ -74,7 +74,7 @@ const getDefaultParamObj = ({

return { [key]: returnVal }
}),
reduce(merge, commonParams)
reduce(merge, commonParams),
)(params)

/**
Expand Down
21 changes: 21 additions & 0 deletions test/__tests__/jsonp.test.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { fakeGetApi } from '@examples/apis-web/'
import fakeGetConfig from '@examples/apis-web/fake-get'
import { ERROR_STRINGS } from '@/constants'

jest.mock('fetch-jsonp')
Expand All @@ -24,6 +25,26 @@ describe('mock data', () => {
})

describe('fake jsonp requests', () => {
test('jsonp options', async () => {
const url = 'http://example-base.com/fake-get/jsonp-options'
const jsonpOptions = {
...fakeGetConfig.jsonpOptions,
charset: 'UTF-8',
}

await fakeGetApi.jsonpOptions()
expect(fetchJsonp).toBeCalledWith(url, jsonpOptions)

const callback = 'test_cb'
const callbackName = 'test_cbName'
await fakeGetApi.jsonpOptions(null, { callback, callbackName })
expect(fetchJsonp).toBeCalledWith(url, {
...jsonpOptions,
jsonpCallback: callback,
jsonpCallbackFunction: callbackName,
})
})

test('async-common-params', async () => {
fetchJsonp.mockResolvedValue({ json: () => data })
const resData = await fakeGetApi.acp()
Expand Down
3 changes: 2 additions & 1 deletion test/__tests__/wx.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -63,11 +63,12 @@ describe('middleware', () => {
expect(ctx.req.prefix).toBeDefined()
expect(ctx.req.reqType).toBeDefined()
expect(ctx.req.reqParams).toBeDefined()
expect(ctx.req.callbackName).toBeDefined()
expect(ctx.req.axiosOptions).toBeDefined()
expect(ctx.req.jsonpOptions).toBeDefined()
expect(ctx.req.reqFnParams).toBeDefined()

expect(ctx.req.callbackName).toBeUndefined()

await next()

expect(ctx.reqTime).toBeDefined()
Expand Down

0 comments on commit 1f379af

Please sign in to comment.