Estoy luchando por encontrar documentación o ejemplos de implementación de un indicador de progreso de carga usando fetch .
Esta es la única referencia que he encontrado hasta ahora , que dice:
Los eventos de progreso son una característica de alto nivel que no llegará a buscar por ahora. Puede crear el suyo propio mirando el
Content-Length
encabezado y utilizando un flujo de transferencia para monitorear los bytes recibidos.Esto significa que puede manejar explícitamente las respuestas sin una forma
Content-Length
diferente. Y, por supuesto, incluso siContent-Length
está ahí, puede ser una mentira. Con las corrientes puedes manejar estas mentiras como quieras.
¿Cómo escribiría "un flujo de paso a través para monitorear los bytes" enviados? Si hace algún tipo de diferencia, estoy tratando de hacer esto para impulsar la carga de imágenes desde el navegador a Cloudinary .
NOTA : estoy no interesado en la biblioteca Cloudinary JS , ya que depende de jQuery y mi aplicación no lo hace. Solo estoy interesado en el procesamiento de transmisión necesario para hacer esto con javascript nativo y fetch
polyfill de Github .
fuente
Respuestas:
Las transmisiones están comenzando a aterrizar en la plataforma web ( https://jakearchibald.com/2016/streams-ftw/ ) pero aún son los primeros días.
Pronto podrá proporcionar un flujo como el cuerpo de una solicitud, pero la pregunta abierta es si el consumo de ese flujo se relaciona con los bytes cargados.
Los redireccionamientos particulares pueden resultar en la retransmisión de datos a la nueva ubicación, pero los flujos no pueden "reiniciarse". Podemos solucionar esto convirtiendo el cuerpo en una devolución de llamada que se puede llamar varias veces, pero debemos estar seguros de que exponer la cantidad de redireccionamientos no es una fuga de seguridad, ya que sería la primera vez en la plataforma que JS podría detectar eso.
Algunos se preguntan si tiene sentido vincular el consumo de flujo con los bytes cargados.
En pocas palabras: esto aún no es posible, pero en el futuro se manejará mediante transmisiones o mediante algún tipo de devolución de llamada de nivel superior
fetch()
.fuente
Mi solución es usar axios , que admite esto bastante bien:
Tengo un ejemplo para usar esto en reaccionar en github.
fuente
axios
Usofetch
oXMLHttpRequest
bajo el capó?axios
no se usafetch
debajo del capó y no tiene tal soporte. Literalmente lo estoy escribiendo ahora para ellos.No creo que sea posible. El borrador dice:
(respuesta anterior):
el primer ejemplo en el capítulo Fetch API brinda información sobre cómo:
Aparte de su uso del
Promise
constructor antipattern , puede ver queresponse.body
es un Stream desde el que puede leer byte a byte usando un Reader, y puede disparar un evento o hacer lo que quiera (por ejemplo, registrar el progreso) para cada uno de ellos.Sin embargo, la especificación de Streams no parece estar del todo terminada, y no tengo idea de si esto ya funciona en alguna implementación de recuperación.
fuente
fetch
. Me interesan los indicadores de progreso para cargar un archivo.Promise
constructor no es necesario.Response.body.getReader()
devuelve unPromise
. Consulte Cómo resolver ungetReader
no devuelve una promesa. No tengo idea de qué tiene esto que ver con la publicación que vinculó..getReader()
el.read()
método correcto devuelve aPromise
. Eso es lo que intentaba transmitir. El enlace es para aludir a la premisa de que si se puede verificar el progreso para la descarga, se puede verificar el progreso para la carga. Elabore un patrón que arroje el resultado esperado, en un grado apreciable; ese es el progreso para lafetch()
carga. No he encontrado la forma deecho
un objetoBlob
uFile
en jsfiddle, probablemente se esté perdiendo algo simple. Probar ellocalhost
archivo de carga muy rápidamente, sin imitar las condiciones de la red; aunque acabo de recordarNetwork throttling
.Actualización: como dice la respuesta aceptada, ahora es imposible. pero el siguiente código solucionó nuestro problema durante algún tiempo. Debo agregar que al menos tuvimos que cambiar al uso de una biblioteca basada en XMLHttpRequest.
gracias a este enlace: https://jakearchibald.com/2016/streams-ftw/
fuente
content-length
! == longitud del cuerpo. Cuando se usa la compresión http (común para descargas grandes), la longitud del contenido es el tamaño después de la compresión http, mientras que la longitud es el tamaño después de que se extrajo el archivo.Dado que ninguna de las respuestas resuelve el problema.
Solo por el bien de la implementación, puede detectar la velocidad de carga con una pequeña porción inicial de tamaño conocido y el tiempo de carga se puede calcular con la longitud del contenido / la velocidad de carga. Puede utilizar este tiempo como estimación.
fuente
Una posible solución sería utilizar el
new Request()
constructor y luego verificar elRequest.bodyUsed
Boolean
atributopara determinar si la transmisión es
distributed
Devuelve el
fetch()
Promise
desde dentro.then()
encadenado a la.read()
llamada recursiva deReadableStream
cuandoRequest.bodyUsed
es igual atrue
.Tenga en cuenta que el enfoque no lee los bytes de
Request.body
los bytes a medida que se transmiten al punto final. Además, la carga podría completarse mucho antes de que se devuelva la respuesta completa al navegador.fuente
fuente
La parte clave es ReadableStream ≪ obj_response .body≫.
Muestra:
Puede probar su ejecución en una página enorme, por ejemplo, https://html.spec.whatwg.org/ y https://html.spec.whatwg.org/print.pdf . CtrlShiftJ y cargue el código en formato.
(Probado en Chrome).
fuente