01
前言金三银四,又快到了新的一年换工作的时候了,各种妖魔鬼怪的问题又出来了,比如 "如何根据手机壳颜色来动态改变手机主题颜色",虽然这个不是面试题,但是现在想想还是依然很好笑。
最近我会放几篇关于前端一些面试题,因为我主要是做Vue的,所以可能react的相关问题不多,但也会涉及。
今天先给大家说一个我曾经面试遇到过一个看似比较幼稚的问题,但实际还真是自己的知识盲区。— 如何中断一个网络请求?
02
背景知识
XMLHttpRequest我们都知道在前端进行网张请求的时候,基本上都是采用XMLHttpRequest这个对象。看一下官网中对此的简单介绍
"XMLHttpRequest 对象用于在后台与服务器交换数据。
什么是 XMLHttpRequest 对象?XMLHttpRequest 对象用于在后台与服务器交换数据。
XMLHttpRequest 对象是开发者的梦想,因为您能够:
在不重新加载页面的情况下更新网页在页面已加载后从服务器请求数据在页面已加载后从服务器接收数据在后台向服务器发送数据所有现代的浏览器都支持 XMLHttpRequest 对象。" 出自 《w3school》
之前用 JQuery的时候 $.ajax 底层也是用的这个对象,包括现在非常流程的前端请求框架 axios web底层也是用的这个对象(并不是都是采用这个对象,axios是根据不同的运行环境采用不用的工作原理)
fetch简单介绍一下什么是 fetch
"Fetch API 提供了一个 JavaScript 接口,用于访问和操纵 HTTP 管道的一些具体部分,例如请求和响应。它还提供了一个全局 fetch() 方法,该方法提供了一种简单,合理的方式来跨网络异步获取资源。
这种功能以前是使用 XMLHttpRequest 实现的。Fetch 提供了一个更理想的替代方案,可以很容易地被其他技术使用,例如 Service Workers。Fetch 还提供了专门的逻辑空间来定义其他与 HTTP 相关的概念,例如 CORS 和 HTTP 的扩展。"出自 《MDN Web Docs》
也就是说现在前端进行网络请求有两种不同的实现方式,可以使用 XMLHttpRequest 方式 也可以 采用 Fetch的方式。
fetch现在可能用的还不是很多,基本上还是以 XMLHttpRequest为主。
好,简单介绍一下背景知识之后,我们正式开始今天的话题:如何中断一个正在发送的网络请求?
03
如何中断一个网络请求
上面我们介绍了在前端中两种请求网络的不同实现方式,现在我们就分别介绍这两种方式如何中断请求。
XMLHttpRequest
XMLHttpRequest对象带了一个方法 abort() 可以实现这个效果,但现实是我们很少去用原生的这样的写法去请求网络,都是采用比较成熟的第三方框架去实现,所以我们这里着重介绍一下基于 axios 的实现方式。
基于 CancelToken方式:
代码语言:javascript代码运行次数:0运行复制const CancelToken = axios.CancelToken;
const source = CancelToken.source();
axios.get('/user/12345', {
cancelToken: source.token
}).catch(function(thrown) {
if (axios.isCancel(thrown)) {
console.log('Request canceled', thrown.message);
} else {
// 处理错误
}
});
axios.post('/user/12345', {
name: 'new name'
}, {
cancelToken: source.token
})
// 取消请求(message 参数是可选的)
source.cancel('Operation canceled by the user.');基于 executor函数:
代码语言:javascript代码运行次数:0运行复制const CancelToken = axios.CancelToken;
let cancel;
axios.get('/user/12345', {
cancelToken: new CancelToken(function executor(c) {
// executor 函数接收一个 cancel 函数作为参数
cancel = c;
})
});
// cancel the request
cancel();
Fetch
先看一下浏览的支持情况吧
我们先使用AbortController()构造函数创建一个控制器,
然后使用 AbortController.signal属性获取其关联 AbortSignal 对象的引用。
当一个 fetch request 初始化,我们把 AbortSignal 作为一个选项传递到到请求对象(如下 { signal })。这将 signal 和 controller 与这个 fetch request 相关联,然后允许我们通过调用 AbortController.abort() 中止请求,
如下第二个事件监听函数。
代码语言:javascript代码运行次数:0运行复制const controller = new AbortController();
let signal = controller.signal;
const downloadBtn = document.querySelector('.download');
const abortBtn = document.querySelector('.abort');
downloadBtn.addEventListener('click', fetchVideo);
abortBtn.addEventListener('click', function() {
controller.abort();
console.log('Download aborted');
});
function fetchVideo() {
//...
fetch(url, {signal}).then(function(response) {
//...
}).catch(function(e) {
reports.textContent = 'Download error: ' + e.message;
})
}当 abort() 被调用时,这个 fetch() promise 将 reject 一个名为 AbortError 的 DOMException。
04
写在最后大多数小伙伴可能都不知道发出去请求还能中断,原来我也不知道,但是后来查阅相关资料之后发现的确实是可以前端博大精深。
在一些面试中这些问题虽然平时用不到(也是有点用处的)但确是面试官非常喜欢问的知识,可能他们也不一定会,所以这里介绍给大家