Sam*_*Lee 168 javascript ajax fetch-api
有一个用于从JavaScript发出请求的新API:fetch().是否有任何内置机制可以在飞行中取消这些请求?
Sud*_*Plz 221
fetch现在支持signal截至2017年9月20日的参数,但并非所有浏览器都支持此atm.
这是我们很快就会看到的变化,因此您应该可以使用AbortControllers 取消请求AbortSignal.
它的工作方式是这样的:
第1步:你创建一个AbortController(现在我只是用过这个)
const controller = new AbortController()
第2步:你得到这样AbortController的信号:
const signal = controller.signal
第3步:你signal像这样传递给fetch:
fetch(urlToFetch, {
method: 'get',
signal: signal, // <------ This is our AbortSignal
})
Run Code Online (Sandbox Code Playgroud)
第4步:在需要时立即中止:
controller.abort();
以下是它如何工作的示例(适用于Firefox 57+):
<script>
// Create an instance.
const controller = new AbortController()
const signal = controller.signal
/*
// Register a listenr.
signal.addEventListener("abort", () => {
console.log("aborted!")
})
*/
function beginFetching() {
console.log('Now fetching');
var urlToFetch = "https://httpbin.org/delay/3";
fetch(urlToFetch, {
method: 'get',
signal: signal,
})
.then(function(response) {
console.log(`Fetch complete. (Not aborted)`);
}).catch(function(err) {
console.error(` Err: ${err}`);
});
}
function abortFetching() {
console.log('Now aborting');
// Abort.
controller.abort()
}
</script>
<h1>Example of fetch abort</h1>
<hr>
<button onclick="beginFetching();">
Begin
</button>
<button onclick="abortFetching();">
Abort
</button>Run Code Online (Sandbox Code Playgroud)
spr*_*pro 58
我不相信有一种方法可以使用现有的fetch API取消请求.有关它的讨论正在https://github.com/whatwg/fetch/issues/27上进行
2017年5月更新:仍无法解决.请求无法取消.更多讨论,请访问https://github.com/whatwg/fetch/issues/447
Jay*_*yen 15
https://developers.google.com/web/updates/2017/09/abortable-fetch
建立:
// setup AbortController
const controller = new AbortController();
// signal to pass to fetch
const signal = controller.signal;
// fetch as usual
fetch(url, { signal }).then(response => {
...
}).catch(e => {
// catch the abort if you like
if (e.name === 'AbortError') {
...
}
});
// when you want to abort
controller.abort();
Run Code Online (Sandbox Code Playgroud)
中止: __CODE__
在边缘16(2017-10-17),firefox 57(2017-11-14),桌面游猎11.1(2018-03-29),ios safari 11.4(2018-03-29),chrome 67(2018-05)工作-29),以及之后.
自2018年2月起,fetch()可以使用 Chrome下面的代码取消(阅读使用可读流以启用Firefox支持).没有错误catch()提起,这是一个临时的解决方案,直到AbortController完全采用.
fetch('YOUR_CUSTOM_URL')
.then(response => {
if (!response.body) {
console.warn("ReadableStream is not yet supported in this browser. See https://developer.mozilla.org/en-US/docs/Web/API/ReadableStream")
return response;
}
// get reference to ReadableStream so we can cancel/abort this fetch request.
const responseReader = response.body.getReader();
startAbortSimulation(responseReader);
// Return a new Response object that implements a custom reader.
return new Response(new ReadableStream(new ReadableStreamConfig(responseReader)));
})
.then(response => response.blob())
.then(data => console.log('Download ended. Bytes downloaded:', data.size))
.catch(error => console.error('Error during fetch()', error))
// Here's an example of how to abort request once fetch() starts
function startAbortSimulation(responseReader) {
// abort fetch() after 50ms
setTimeout(function() {
console.log('aborting fetch()...');
responseReader.cancel()
.then(function() {
console.log('fetch() aborted');
})
},50)
}
// ReadableStream constructor requires custom implementation of start() method
function ReadableStreamConfig(reader) {
return {
start(controller) {
read();
function read() {
reader.read().then(({done,value}) => {
if (done) {
controller.close();
return;
}
controller.enqueue(value);
read();
})
}
}
}
}
Run Code Online (Sandbox Code Playgroud)
正如@spro所说,目前还没有合适的解决方案。
但是,如果您有正在进行的响应并且正在使用 ReadableStream,则可以关闭流以取消请求。
fetch('http://example.com').then((res) => {
const reader = res.body.getReader();
/*
* Your code for reading streams goes here
*/
// To abort/cancel HTTP request...
reader.cancel();
});
Run Code Online (Sandbox Code Playgroud)