javascript - Como faço para cancelar uma requisição HTTP fetch()?
Existe uma nova API para fazer requisições a partir do JavaScript: fetch(). Existe algum mecanismo incorporado para cancelar essas requisições em andamento?
Resposta #1
Resumo:
fetch agora suporta um parâmetro signal desde 20 de setembro de 2017, mas nem todos os navegadores parecem suportar isso no momento.
ATUALIZAÇÃO 2020: A maioria dos principais navegadores (Edge, Firefox, Chrome, Safari, Opera e alguns outros) suporta o recurso, que se tornou parte do padrão vivo do DOM. (em 5 de março de 2020)
Esta é uma mudança que veremos muito em breve, e portanto você deverá ser capaz de cancelar uma solicitação usando um AbortController com um AbortSignal.
Versão Longa
Como:
O jeito que funciona é assim:
Passo 1: Você cria um AbortController (Por enquanto eu apenas usei este)
const controller = new AbortController()
Passo 2: Você obtém o sinal do AbortController assim:
const signal = controller.signal
Passo 3: Você passa o signal para o fetch assim:
fetch(urlToFetch, {
method: 'get',
signal: signal, // <------ This is our AbortSignal
})
Passo 4: Basta abortar sempre que precisar:
controller.abort();
Aqui está um exemplo de como isso funcionaria (funciona no Firefox 57+):
// 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()
}<h1>Example of fetch abort</h1>
<hr>
<button onclick="beginFetching();">Begin</button>
<button onclick="abortFetching();">Abort</button>Fontes:
- A versão final do AbortController foi adicionada à especificação do DOM
- O PR correspondente à especificação de fetch agora foi mesclado.
- O rastreamento de bugs do navegador sobre a implementação do AbortController está disponível aqui: Firefox: #1378342, Chromium: #750599, WebKit: #174980, Edge: #13009916.
Resposta #2
https://developers.google.com/web/updates/2017/09/abortable-fetch
https://dom.spec.whatwg.org/#aborting-ongoing-activities
// 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();
funciona no Edge 16 (17-10-2017), Firefox 57 (14-11-2017), Safari para desktop 11.1 (29-03-2018), Safari no iOS 11.4 (29-03-2018), Chrome 67 (29-05-2018) e posteriores.
em navegadores mais antigos, você pode usar o polyfill whatwg-fetch do GitHub e o polyfill AbortController. você também pode detectar navegadores mais antigos e usar os polyfills condicionalmente:
import 'abortcontroller-polyfill/dist/abortcontroller-polyfill-only'
import {fetch} from 'whatwg-fetch'
// use native browser implementation if it supports aborting
const abortableFetch = ('signal' in new Request('')) ? window.fetch : fetch
