文章插图
几乎在所有面向用户或企业的应用程序中,所呈现出来的信息都不是一成不变的,即数据都是动态的,由某个或者多个后台服务所提供 。那么就不可避免地会涉及到网络请求,而对于不同企业肯定有不同的业务场景 。
在一个功能完善的应用程序呈现给用户之前,前后端开发人员必须先根据产品经理提供的业务需求文档协商建立起格式良好的接口契约,然后再经过开发联调测试验证部署上线等一系列流程之后才具有可用性,才能展现在用户面前供用户使用 。
但是可能并不是在任何场景下,我们都需要关心网络请求的响应结果,或者说在某些场景下,我们只需要关心最新的有效的网络请求,对于老旧的失效的网络请求,我们甚至可以忽略它的存在 。
我们知道,从浏览器发起一次网络请求,到建立TCP链接(对于HTTPS协议还需要建立额外的TLS连接)以及DNS域名解析,再到发送请求数据报文,最终服务器处理请求并响应数据,期间会不停占用客户端和服务器资源 。
如果该网络请求对于我们而言已经无效,那么我们就可以通过手动中断请求,来提前释放被占用的资源,减少不必要的资源开销 。
例如考虑以下场景:
- 在Vue或React单页应用中,组件A挂载完毕之后向后台服务发起请求拉取数据,但是由于加载过慢,用户可能期间发生路由跳转或回退,导致组件A卸载,但是组件内部的网络请求并没有立即停止下来,此时的响应数据对于已卸载的组件A而言已经无效 。若刚好此时请求响应错误,就可能导致前端实现的兜底弹窗出现在跳转后的页面中,造成视觉干扰;
- 页面存在定时轮询业务,即固定间隔一段时间再次发起请求,这样就可能存在多个请求间的竞争关系,如果上一个请求的响应速度比最近一次请求的响应速度慢,则前者就会覆盖后者,从而导致数据错乱;
- 类似于关键字搜索或模糊查询等需要频繁发起网络请求的相关业务,可能在一定程度上为了优化程序的执行性能,减少冗余的网络IO,我们会使用防抖(debounce)函数来对请求逻辑进行包装,减少查询次数以降低服务器压力,但是依旧避免不了由于加载耗时过长导致新老请求数据错乱的问题;
- 针对前端大文件上传等上传服务,需要实现上传进度的暂停与恢复,即断点续传 。
在前端领域,个人觉得有几种比较常见的网络请求方案:浏览器原生支持的XMLHttpRequest对象,同时兼容浏览器端和NodeJS服务端的第三方HTTP库AxIOS和大部分浏览器最新实现的Fetch API 。本文主要基于以上三种请求方案讲解一下各自中断请求的方式,文中若有错误,还请指正 。
1、XMLHttpRequest
浏览器原生实现的XMLHttpRequest(以下简称XHR)构造函数对于我们来说已经是再熟悉不过了,但是在实际应用中,大部分场景下可能我们并不需要去主动实例化XHR构造函数,毕竟实例化之后还需要通过调用open和send等一系列的官方API才能实现与服务器的数据交互,操作细节稍微繁琐 。
相反我们一般会推荐使用社区实现的第三方库来方便我们简化操作流程,提升开发效率,例如下一节将要讲述的Axios 。但即便是Axios,在浏览器端其底层依旧是通过XHR构造函数来实现网络IO的,因此这一小节有必要对XHR的相关知识点进行回顾和讲解 。
首先抛出一个基础示例:
复制/** * @description: 基于 XHR 封装的网络请求工具函数 * @param {String} url 请求接口地址 * @param {Document | XMLHttpRequestBodyInit | null} body 请求体 * @param {Object} requestHeader 请求头 * @param {String} method 请求方法 * @param {String} responseType 设置响应内容的解析格式 * @param {Boolean} async 请求是否异步 * @param {Number} timeout 设置请求超时时间(单位:毫秒) * @param {Boolean} withCredentials 设置跨域请求是否允许携带 cookies 或 Authorization header 等授权信息 * @return {Promise} 可包含响应内容的 Promise 实例*/function request({url,body = null,requestHeader = {'Content-Type': 'Application/x-www-form-urlencoded'},method = 'GET',responseType = 'text',async = true,timeout = 30000,withCredentials = false,} = {}) {return new Promise((resolve, reject) => {if (!url) {return reject(new TypeError('the required parameter [url] is missing.'));}if (method.toLowerCase() === 'get' && body) {url += `?${request.serialize(body)}`;body = null;}const xhr = new XMLHttpRequest();xhr.open(method, url, async);if (async) {xhr.responseType = responseType;xhr.timeout = timeout;}xhr.withCredentials = withCredentials;if (requestHeader && typeof requestHeader === 'object') {Object.keys(requestHeader).forEach(key => xhr.setRequestHeader(key, requestHeader[key]));}xhr.onreadystatechange = function onReadyStateChange() {if (xhr.readyState === XMLHttpRequest.DONE) {if (xhr.status >= 200 && xhr.status < 300 || xhr.status === 304) {resolve(xhr.response);}}};xhr.onerror = function onError(error) {console.log(error);reject({ message: '请求出错,请稍后重试' });};xhr.ontimeout = function onTimeout() {reject({ message: '接口超时,请稍后重试' });};xhr.send(body ? JSON.stringify(body) : null);});}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.
推荐阅读
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- 如何查找被删聊天记录?
- 客厅装修如何设计壁纸
- 美式田园地砖如何搭配
- 6款适合春季的时尚运动 如何制定春季健身计划
- 中医教你春季如何养肝 做好饮食很关键
- 老人春季如何养生 推荐6大春季养生妙招
- 眼屎增多或是眼病的预示 春季该如何护眼
- 如何辨别红茶的好坏,蒲公英与苦荞茶的作用与功效
- 小白一定要看,如何关闭和设置电脑开机时的软件自启动
- 如何通过docker run启动一个pod