Skip to content

Commit 6c8f797

Browse files
authored
fix: 修复请求体处理 (#70)
1 parent fa19919 commit 6c8f797

4 files changed

Lines changed: 248 additions & 4 deletions

File tree

packages/basic/src/utils/create/index.ts

Lines changed: 30 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,17 @@ import { createMockServiceByData } from './mockData';
1616
import { sseRequester } from './sseRequester';
1717

1818
import Config from '../../config';
19-
import { overwriteErrorMsgFieldIfSpecified } from './utils';
19+
import {
20+
overwriteErrorMsgFieldIfSpecified,
21+
isFormData,
22+
isArrayBuffer,
23+
isBuffer,
24+
isStream,
25+
isFile,
26+
isBlob,
27+
isArrayBufferView,
28+
isObject,
29+
} from './utils';
2030
import { default as builtInInterceptors } from './interceptors';
2131

2232
const getData = (str) => new Function('return ' + str)();
@@ -160,7 +170,7 @@ function download(url) {
160170
function formatCallConnectorPath(path: string, connectionName: string): string {
161171
const sysPrefixPath = window.appInfo?.sysPrefixPath;
162172
if (sysPrefixPath) {
163-
path = path?.replace(sysPrefixPath, "");
173+
path = path?.replace(sysPrefixPath, '');
164174
}
165175

166176
// /api/connectors/connector1/namespace1/getA
@@ -169,7 +179,7 @@ function formatCallConnectorPath(path: string, connectionName: string): string {
169179
throw Error('unexpected path when use CallConnector');
170180
}
171181
const [prefix1, prefix2, connectorName, ...rt] = pathItemList;
172-
return `${sysPrefixPath ? sysPrefixPath : ""}/${prefix1}/${prefix2}/${connectorName}/${connectionName}/${rt.join('/')}`;
182+
return `${sysPrefixPath ? sysPrefixPath : ''}/${prefix1}/${prefix2}/${connectorName}/${connectionName}/${rt.join('/')}`;
173183
}
174184

175185
export function genBaseOptions(requestInfo) {
@@ -201,12 +211,28 @@ export function genBaseOptions(requestInfo) {
201211
transformRequest: [
202212
function (data, headers) {
203213
try {
204-
if (headers['Content-Type'] !== 'application/x-www-form-urlencoded') {
214+
if (
215+
isFormData(data) ||
216+
isArrayBuffer(data) ||
217+
isBuffer(data) ||
218+
isStream(data) ||
219+
isFile(data) ||
220+
isBlob(data)
221+
) {
222+
return data;
223+
}
224+
225+
if (isArrayBufferView(data)) {
226+
return data.buffer;
227+
}
228+
229+
if (isObject(data) || headers['Content-Type'].includes('application/json')) {
205230
// 对于 JSON 请求,序列化的时候保持对象的形状,不让 undefined 字段消失。便于服务端识别
206231
const replacerToKeepUndefinedFields = (_: string, value: unknown) => (value === undefined ? null : value);
207232
const request = JSONbig.stringify(data, replacerToKeepUndefinedFields);
208233
return request;
209234
}
235+
210236
return data;
211237
} catch (error) {
212238
return data;

packages/basic/src/utils/create/utils.ts

Lines changed: 180 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,3 +46,183 @@ export function stringifyWithLoopProtection(obj: any, replacer?: any, space?: an
4646
hasCircleProp,
4747
};
4848
}
49+
50+
const toString = Object.prototype.toString;
51+
52+
/**
53+
* Determine if a value is an Array
54+
*
55+
* @param {Object} val The value to test
56+
* @returns {boolean} True if value is an Array, otherwise false
57+
*/
58+
export function isArray(val) {
59+
return toString.call(val) === '[object Array]';
60+
}
61+
62+
/**
63+
* Determine if a value is undefined
64+
*
65+
* @param {Object} val The value to test
66+
* @returns {boolean} True if the value is undefined, otherwise false
67+
*/
68+
export function isUndefined(val) {
69+
return typeof val === 'undefined';
70+
}
71+
72+
/**
73+
* Determine if a value is a Buffer
74+
*
75+
* @param {Object} val The value to test
76+
* @returns {boolean} True if value is a Buffer, otherwise false
77+
*/
78+
export function isBuffer(val) {
79+
return (
80+
val !== null &&
81+
!isUndefined(val) &&
82+
val.constructor !== null &&
83+
!isUndefined(val.constructor) &&
84+
typeof val.constructor.isBuffer === 'function' &&
85+
val.constructor.isBuffer(val)
86+
);
87+
}
88+
89+
/**
90+
* Determine if a value is an ArrayBuffer
91+
*
92+
* @param {Object} val The value to test
93+
* @returns {boolean} True if value is an ArrayBuffer, otherwise false
94+
*/
95+
export function isArrayBuffer(val) {
96+
return toString.call(val) === '[object ArrayBuffer]';
97+
}
98+
99+
/**
100+
* Determine if a value is a FormData
101+
*
102+
* @param {Object} val The value to test
103+
* @returns {boolean} True if value is an FormData, otherwise false
104+
*/
105+
export function isFormData(val) {
106+
return typeof FormData !== 'undefined' && val instanceof FormData;
107+
}
108+
109+
/**
110+
* Determine if a value is a view on an ArrayBuffer
111+
*
112+
* @param {Object} val The value to test
113+
* @returns {boolean} True if value is a view on an ArrayBuffer, otherwise false
114+
*/
115+
export function isArrayBufferView(val) {
116+
var result;
117+
if (typeof ArrayBuffer !== 'undefined' && ArrayBuffer.isView) {
118+
result = ArrayBuffer.isView(val);
119+
} else {
120+
result = val && val.buffer && val.buffer instanceof ArrayBuffer;
121+
}
122+
return result;
123+
}
124+
125+
/**
126+
* Determine if a value is a String
127+
*
128+
* @param {Object} val The value to test
129+
* @returns {boolean} True if value is a String, otherwise false
130+
*/
131+
export function isString(val) {
132+
return typeof val === 'string';
133+
}
134+
135+
/**
136+
* Determine if a value is a Number
137+
*
138+
* @param {Object} val The value to test
139+
* @returns {boolean} True if value is a Number, otherwise false
140+
*/
141+
export function isNumber(val) {
142+
return typeof val === 'number';
143+
}
144+
145+
/**
146+
* Determine if a value is an Object
147+
*
148+
* @param {Object} val The value to test
149+
* @returns {boolean} True if value is an Object, otherwise false
150+
*/
151+
export function isObject(val) {
152+
return val !== null && typeof val === 'object';
153+
}
154+
155+
/**
156+
* Determine if a value is a plain Object
157+
*
158+
* @param {Object} val The value to test
159+
* @return {boolean} True if value is a plain Object, otherwise false
160+
*/
161+
export function isPlainObject(val) {
162+
if (toString.call(val) !== '[object Object]') {
163+
return false;
164+
}
165+
166+
var prototype = Object.getPrototypeOf(val);
167+
return prototype === null || prototype === Object.prototype;
168+
}
169+
170+
/**
171+
* Determine if a value is a Date
172+
*
173+
* @param {Object} val The value to test
174+
* @returns {boolean} True if value is a Date, otherwise false
175+
*/
176+
export function isDate(val) {
177+
return toString.call(val) === '[object Date]';
178+
}
179+
180+
/**
181+
* Determine if a value is a File
182+
*
183+
* @param {Object} val The value to test
184+
* @returns {boolean} True if value is a File, otherwise false
185+
*/
186+
export function isFile(val) {
187+
return toString.call(val) === '[object File]';
188+
}
189+
190+
/**
191+
* Determine if a value is a Blob
192+
*
193+
* @param {Object} val The value to test
194+
* @returns {boolean} True if value is a Blob, otherwise false
195+
*/
196+
export function isBlob(val) {
197+
return toString.call(val) === '[object Blob]';
198+
}
199+
200+
/**
201+
* Determine if a value is a Function
202+
*
203+
* @param {Object} val The value to test
204+
* @returns {boolean} True if value is a Function, otherwise false
205+
*/
206+
export function isFunction(val) {
207+
return toString.call(val) === '[object Function]';
208+
}
209+
210+
/**
211+
* Determine if a value is a Stream
212+
*
213+
* @param {Object} val The value to test
214+
* @returns {boolean} True if value is a Stream, otherwise false
215+
*/
216+
export function isStream(val) {
217+
return isObject(val) && isFunction(val.pipe);
218+
}
219+
220+
/**
221+
* Determine if a value is a URLSearchParams object
222+
*
223+
* @param {Object} val The value to test
224+
* @returns {boolean} True if value is a URLSearchParams object, otherwise false
225+
*/
226+
export function isURLSearchParams(val) {
227+
return typeof URLSearchParams !== 'undefined' && val instanceof URLSearchParams;
228+
}

packages/basic/tests/bigNumber/replacer.spec.js

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,4 +14,19 @@ describe('JSONbig replacer', () => {
1414

1515
expect(result).toBe('{"a":1,"b":null,"c":"test"}');
1616
});
17+
18+
it('should handle undefined', () => {
19+
const result = JSONbig.stringify(undefined);
20+
expect(result).toBe(undefined);
21+
});
22+
23+
it('should handle null', () => {
24+
const result = JSONbig.stringify(null);
25+
expect(result).toBe('null');
26+
});
27+
28+
it('should handle empty string', () => {
29+
const result = JSONbig.stringify('');
30+
expect(result).toBe('""');
31+
});
1732
});
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
const {
2+
isFormData,
3+
isArrayBuffer,
4+
isBuffer,
5+
isStream,
6+
isFile,
7+
isBlob,
8+
isArrayBufferView,
9+
} = require('../../src/utils/create/utils');
10+
11+
describe('request utils', () => {
12+
it('should utils correctly', () => {
13+
const data = {};
14+
15+
expect(isFormData(data)).toBe(false);
16+
expect(isArrayBuffer(data)).toBe(false);
17+
expect(isBuffer(data)).toBe(false);
18+
expect(isStream(data)).toBe(false);
19+
expect(isFile(data)).toBe(false);
20+
expect(isBlob(data)).toBe(false);
21+
expect(isArrayBufferView(data)).toBe(false);
22+
});
23+
});

0 commit comments

Comments
 (0)