fetch常用的库有whatwg-fetch,node-fetch,isomorphic-fetch。
h5项目中用的是whatwg-fetch,本质上就是为不支持fetch的浏览器做了polyfill。node-fetch是基于http库运行在node环境。但通常用isomorphic-fetch,本质上就是对前两者的封装,同时支持在浏览器和node上运行。
同构项目中用isomorphic-fetch,axios的都有,差别不大,用啥都行。
whatwg-fetch本身比较简单,源代码也不长,不赘述。项目中直接用whatwg-fetch库的话,不太适合团队维护,最好进行二次封装,尽量开箱即用,避免每个人的fetch写的都不一样。
例如设个超时时间,用promise.race很容易实现:(伪代码)
const timeoutPromise = async(timeout) => { await sleep(timeout); throw new TimeoutError(timeout); }; export default async(config) => { const { timeout = 60000, ...fetchConfig } = config; return await Promise.race([timeoutPromise(timeout), sendRequest(fetchConfig)]); };
whatwg-fetch默认是不发送cookie的,不管是同域还是跨域,所以二次封装时,无脑封装一下options参数:
const basicFetchOptions = { credentials: 'include', // cookie既可以同域发送,也可以跨域发送。 // credentials 默认值是 omit 表示不发送cookie,还可以设为 same-origin 表示cookie只能同域发送,不能跨域发送 };
Post可以根据是否是Json格式进行封装:
if ( /* 正则判 headers['Content-Type'] 是否是 application/json */ ) { options.body = JSON.stringify(data); } else { options.body = querystring.stringify(data)); // data 记得事先扁平化处理下 } options.headers = { 'Content-Type': 'application/x-www-form-urlencoded;charset=utf-8', // file 会用组件封装单独处理 ...options.headers, };
还需要根据业务特性和项目结构,封装:返回值,异常,mock数据,缓存数据(弄个eventBus,请求状态标记为ing或done,在第一个请求request和response期间,相同的请求都返回和第一个请求相同的response)等。封装个团队能用的fetch不难,但细节较多。