能否暂停而非终止HTTP fetch()请求并后续恢复?
能否暂停并恢复
fetch()请求? 不行,原生fetch() API本身不支持暂停后恢复的功能,这本质上是因为HTTP协议没有设计“暂停请求”的机制——一旦请求发送出去,要么正常完成、要么被终止,没有中间暂停的状态。
不过你可以通过以下方式模拟类似的效果:
利用HTTP范围请求实现断点续传
如果你请求的是支持范围请求的资源(比如静态文件),可以在发起fetch时通过Range头指定要获取的字节范围。暂停时用AbortController终止当前请求,恢复时重新发起请求,带上Range: bytes=已接收字节数-的头,服务器会返回剩余部分的内容,最后把前后两次的响应数据拼接起来即可。
示例代码大概是这样:let controller; let receivedBytes = 0; let responseData = new Blob(); async function startOrResumeFetch(url) { controller = new AbortController(); try { const response = await fetch(url, { signal: controller.signal, headers: receivedBytes > 0 ? { Range: `bytes=${receivedBytes}-` } : {} }); // 检查是否支持范围请求 if (receivedBytes > 0 && response.status !== 206) { // 服务器不支持,只能重新从头请求 receivedBytes = 0; responseData = new Blob(); return startOrResumeFetch(url); } const reader = response.body.getReader(); while (true) { const { done, value } = await reader.read(); if (done) break; receivedBytes += value.length; responseData = new Blob([responseData, value]); } // 处理完整的responseData } catch (err) { if (err.name !== 'AbortError') throw err; // 暂停时的逻辑,什么都不用做,等待恢复 } } // 暂停请求 function pauseFetch() { controller?.abort(); }用XMLHttpRequest(XHR)替代fetch
XHR同样没有原生暂停功能,但它的进度事件(progress)更容易监听已接收的字节数,结合Range头实现断点续传的逻辑会更直观一些,原理和上面一致。
需要注意的是,这种模拟方式依赖服务器支持范围请求,对于动态接口或者不支持Range的资源,这种方法就不适用了。
内容的提问来源于stack exchange,提问作者brillout
相关产品推荐
相关产品推荐

