Fetch API 是 XMLHttpRequest 实现功能的一个更理想的替代方案,它提供了一个 JavaScript 接口,用于异步的执行 http 请求。
在常规的简单接口调试中,使用 Fetch API 可以在浏览器控制台快速的发起一个接口请求,并查看其返回结果。下面是相关实现的示例(备份:用于快速查找使用)。
Fetch API 执行 Get
请求示例:
1 2 3 4 5 6 7 8 | await fetch(url, { method: 'GET' , credentials: 'include' , headers: { Accept: 'application/json' , 'Content-Type' : 'application/json' , }, }).then(response => response.json()); |
Fetch API 执行 POST
请求示例:
1 2 3 4 5 6 7 8 9 | await fetch(url, { method: 'POST' , credentials: 'include' , body: JSON.stringify(params), headers: { Accept: 'application/json' , 'Content-Type' : 'application/json' , }, }).then(response => response.json()); |
基于 Fetch API 实现 GET
和 POST
请求的简单封装示例(TypeScript):
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 | type PlainObject = Record<string, any>; export interface APIResponse< T = PlainObject> extends PlainObject { data: T; errorNo: number; errorInfo?: string; success?: boolean; } function toQueryString(params?: Record<string, unknown>) { if (!params) return '' ; return Object.entries(params) .map(([key, val]) => `${encodeURIComponent(key)}=${encodeURIComponent( typeof val === 'string' ? val : JSON.stringify(val))}`) .join( '&' ); } function toFormData(params: Record<string, unknown>) { const form = new FormData(); Object.entries(params).forEach(([key, val]) => { form.append(key, typeof val !== 'string' && !(val instanceof Blob) ? JSON.stringify(val) : val); }); return form; } async function handlerResponse< T>(response: Response) { const result: APIResponse< T> = { errorNo: 0, data: [] as never }; try { const res: APIResponse< T> = await response.json(); Object.assign(result, res); result.errorNo = +result.errorNo || 0; } catch (err) { const reason = err as { message?: string }; (window.logger || console).error(`[http][get][err]`, reason.message || reason); if (response.status !== 200) result.errorNo = response.status || -400; result.errorInfo = response.statusText || reason.message; } // logger.debug(`[http][req][response]`, result.errorNo, result); return result; } export const httpRequest = { baseHref: '' , get< T = PlainObject>(url: string, params?: PlainObject, headers?: RequestInit[ 'headers' ]): Promise<APIResponse< T>> { const qs = toQueryString(params); if (qs) url += url.includes( '?' ) ? `&${qs}` : `?${qs}`; if ( this .baseHref && !url.startsWith( this .baseHref)) { url = this .baseHref + url; } return fetch(url, { method: 'GET' , credentials: 'include' , headers: { Accept: 'application/json' , 'Content-Type' : 'application/json' , ...headers, }, }).then(response => handlerResponse< T>(response)); }, post< T = PlainObject>( url: string, params: PlainObject, headers?: RequestInit[ 'headers' ], type : 'json' | 'formdata' | 'payload' = 'json' ): Promise<APIResponse< T>> { if ( this .baseHref && !url.startsWith( this .baseHref)) { url = this .baseHref + url; } return fetch(url, { method: 'POST' , credentials: 'include' , body: type === 'formdata' ? toFormData(params) : type === 'payload' ? toQueryString(params) : JSON.stringify(params), headers: { Accept: 'application/json' , 'Content-Type' : type === 'json' ? 'application/json;charset=UTF-8' : 'application/x-www-form-urlencoded;charset=UTF-8' , ...headers, }, }).then(response => handlerResponse< T>(response)); }, }; |
基于 Fetch API 实现 GET
和 POST
请求的简单封装示例(JavaScript):
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 | function toQueryString(params) { if (!params) return '' ; return Object.entries(params) .map(([key, val]) => `${encodeURIComponent(key)}=${encodeURIComponent( typeof val === 'string' ? val : JSON.stringify(val))}`) .join( '&' ); } function toFormData(params) { const form = new FormData(); Object.entries(params).forEach(([key, val]) => { form.append(key, typeof val !== 'string' && !(val instanceof Blob) ? JSON.stringify(val) : val); }); return form; } async function handlerResponse(response) { const result = { errorNo: 0, data: [] }; try { const res = await response.json(); Object.assign(result, res); result.errorNo = +result.errorNo || 0; } catch (err) { const reason = err; (window.logger || console).error(`[http][get][err]`, reason.message || reason); if (response.status !== 200) result.errorNo = response.status || -400; result.errorInfo = response.statusText || reason.message; } // logger.debug(`[http][req][response]`, result.errorNo, result); return result; } const httpRequest = { baseHref: '' , get(url, params, headers) { const qs = toQueryString(params); if (qs) url += url.includes( '?' ) ? `&${qs}` : `?${qs}`; if ( this .baseHref && !url.startsWith( this .baseHref)) { url = this .baseHref + url; } return fetch(url, { method: 'GET' , credentials: 'include' , headers: { Accept: 'application/json' , 'Content-Type' : 'application/json' , ...headers, }, }).then(response => handlerResponse(response)); }, post( url, params, headers, type ) { if ( this .baseHref && !url.startsWith( this .baseHref)) { url = this .baseHref + url; } return fetch(url, { method: 'POST' , credentials: 'include' , body: type === 'formdata' ? toFormData(params) : type === 'payload' ? toQueryString(params) : JSON.stringify(params), headers: { Accept: 'application/json' , 'Content-Type' : type === 'json' ? 'application/json;charset=UTF-8' : 'application/x-www-form-urlencoded;charset=UTF-8' , ...headers, }, }).then(response => handlerResponse(response)); }, }; |
- https://developer.mozilla.org/zh-CN/docs/Web/API/Fetch_API/Using_Fetch
我以前在開發時,有時用XMLHttpRequest,有時也用fetch,感覺差不多。