react - javascript fetch standard
¿Cómo cancelo una solicitud HTTP fetch()? (5)
TL / DR:
fetch
ahora admite un parámetro de
signal
partir del 20 de septiembre de 2017, pero
no todos los navegadores parecen admitir este cajero automático
.
Sin embargo, este es un cambio que veremos muy pronto, por lo que debería poder cancelar una solicitud utilizando
AbortController
AbortSignal
.
Versión larga
Cómo:
La forma en que funciona es la siguiente:
Paso 1
: creas un
AbortController
(por ahora acabo de usar
this
)
const controller = new AbortController()
Paso 2
: obtienes la señal de
AbortController
como esta:
const signal = controller.signal
Paso 3
: Pasas la
signal
para buscar así:
fetch(urlToFetch, {
method: ''get'',
signal: signal, // <------ This is our AbortSignal
})
Paso 4 : simplemente aborta cada vez que necesites:
controller.abort();
Aquí hay un ejemplo de cómo funcionaría (funciona en 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>
Fuentes:
- La versión final de AbortController se ha agregado a la especificación DOM
- El PR correspondiente para la especificación de búsqueda ahora se fusionó.
- Los errores del navegador que rastrean la implementación de AbortController están disponibles aquí: Firefox: #1378342 , Chromium: #750599 , WebKit: #174980 , Edge: #13009916 .
Hay una nueva API para realizar solicitudes desde JavaScript: fetch (). ¿Existe algún mecanismo incorporado para cancelar estas solicitudes en vuelo?
A partir de febrero de 2018,
fetch()
se puede cancelar con el siguiente código en Chrome (lea
Uso de flujos legibles
para habilitar el soporte de Firefox).
No se produce ningún error para que
catch()
AbortController
, y esta es una solución temporal hasta que se
AbortController
completamente
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();
})
}
}
}
}
No creo que haya una manera de cancelar una solicitud con la API de recuperación existente. Hay una discusión continua al respecto en https://github.com/whatwg/fetch/issues/27
Actualización de mayo de 2017: todavía no hay resolución. Las solicitudes no pueden ser canceladas. Más discusión en https://github.com/whatwg/fetch/issues/447
Por ahora no hay una solución adecuada, como dice @spro.
Sin embargo, si tiene una respuesta en vuelo y está utilizando ReadableStream, puede cerrar la transmisión para cancelar la solicitud.
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();
});
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();
funciona en edge 16 (2017-10-17), firefox 57 (2017-11-14), desktop safari 11.1 (2018-03-29), ios safari 11.4 (2018-03-29), chrome 67 (2018-05 -29), y luego.
en navegadores antiguos, puede usar el polyfill whatwg-fetch de github y el polyfill AbortController . puedes detectar navegadores antiguos y usar los polyfills condicionalmente también:
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