Fetch API简单封装
什么是 Fetch API
Fetch API 提供了一个 JavaScript 接口,用于访问和操纵 HTTP 管道的部分,例如请求和响应。它还提供了一个全局 fetch()方法,该方法提供了一种简单,合理的方式来跨网络异步获取资源。
为什么要使用 Fetch
网络异步获取资源之前是用XMLHttpRequest
(例如常见的 jquery.ajax(),axios 都是这种)获取的,Fetch 提供了一个更好的替代方法。现代浏览器基本都内置了,不用额外引入,IE 也可以使用 polyfill 等一堆插件解决,其他浏览器开箱即用。
为什么要封装 Fetch
- 当接收到一个代表错误的 HTTP 状态码时,从 fetch()返回的 Promise 不会被标记为 reject, 即使该 HTTP 响应的状态码是 404 或 500。相反,它会将 Promise 状态标记为 resolve (但是会将 resolve 的返回值的 ok 属性设置为 false ),仅当网络故障时或请求被阻止时,才会标记为 reject。
- 默认情况下,fetch 不会从服务端发送或接收任何 cookies, 如果站点依赖于用户 session,则会导致未经认证的请求(要发送 cookies,必须设置 credentials 选项)。
- 还有最重要的一点,不用每次都写一堆代码。
简易代码 源码使用了 TypeScript 和 async/await
// fetch-config.ts import Qs from 'qs' export enum ContentType { json = 'application/json;charset=UTF-8', form = 'application/x-www-form-urlencoded; charset=UTF-8' } export enum HttpMethod { get = 'GET', post = 'POST', put = 'PUT', patch = 'PATCH', delete = 'DELETE' } export interface IReqConfig { body?: any method?: string headers?: IHeader token?: string 'Content-Type'?: string } export interface IHeader { 'Content-Type': string 'X-Requested-With': string token: string [propName: string]: any } export const baseUrl = '/' const $req = async (url: string, config: IReqConfig) => { let promise: Response let contentType: string if (config['Content-Type'] !== undefined) { contentType = config['Content-Type'] } else if (config.method === HttpMethod.post) { contentType = ContentType.form } else { contentType = ContentType.json } const reqUrl = (baseUrl + url).replace('//', '/') const headers: Headers = new Headers({ // 如果实例配置没传token过来的话,直接使用保存在sessionStorage的token // 这里假设后端直接读头文件的token字段,我直接用token当字段了,Authorization也同理 token: config.token === undefined ? sessionStorage.token : config.token, 'Content-Type': contentType } as IHeader) if (!config.method || config.method === HttpMethod.get) { promise = await fetch(reqUrl, { headers }) } else if (config.method === HttpMethod.post) { promise = await fetch(reqUrl, { body: Qs.stringify(config.body), headers, method: HttpMethod.post }) } else { promise = await fetch(reqUrl, { body: JSON.stringify(config.body), headers, method: config.method }) } return handleRes(promise) } const handleRes = async (res: Response) => { const parsedRes = await parseRes(res) // 如果res.ok,则请求成功 if (res.ok) { return parsedRes } // 请求失败,返回解析之后的失败的数据 const error = parsedRes throw error } const parseRes = async (res: Response) => { const contentType = res.headers.get('Content-Type') // 判定返回的内容类型,做不同的处理 if (contentType) { if (contentType.indexOf('json') > -1) { return await res.json() } if (contentType.indexOf('text') > -1) { return await res.text() } if (contentType.indexOf('form') > -1) { return await res.formData() } if (contentType.indexOf('video') > -1) { return await res.blob() } } return await res.text() } export default $req
使用的时候
// test.ts import $req, { HttpMethod } from './fetch-config' async function getMethod() { const getUrl: string = 'XXXX' try { const res: any = await $req(getUrl) } catch(e) { // 处理异常 } } async function postMethod() { const postUrl: string = 'XXXX' const reqBody: any = {/* request body */} try { const res: any = await $req(postUrl, { body: reqBody, method: HttpMethod.post }) } catch(e) { // 处理异常 } } async function patchMethod() { const patchUrl: string = 'XXXX' const reqBody: any = {/* request body */} try { const res: any = await $req(patchUrl, { body: reqBody, method: HttpMethod.patch }) } catch(e) { // 处理异常 } }
以上就是 fetch API 的简单封装,如果用的 JavaScript 的话,把类型和枚举去掉就好,没什么差别
相关推荐
zhaojp0 2020-06-27
zlsdmx 2020-04-25
keepdoingit 2020-04-17
Magicsoftware 2020-03-28
李永毅 2020-03-08
星空下的程序猿 2020-02-24
就是那个胖子 2020-01-07
xubzhlin 2019-12-29
春雨的雕刻时光 2019-12-11
TONIYH 2019-11-13
heimu 2017-04-05
haoshuai 2019-04-25
heihahu 2016-08-12
dldx0 2013-02-19
Deng0web 2012-09-01
okokyu 2015-08-02
zry 2012-01-10