progreso barra javascript html5 fetch-api

javascript - barra de progreso jquery



¿Cargar indicadores de progreso para buscar? (8)

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 / velocidad de carga. Puedes usar este tiempo como estimación.

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á en busca por el momento. Puede crear el suyo mirando el encabezado Content-Length y utilizando una secuencia de transferencia para monitorear los bytes recibidos.

Esto significa que puede manejar explícitamente las respuestas sin una Content-Length diferente. Y, por supuesto, incluso si Content-Length está allí, puede ser una mentira. Con las transmisiones puedes manejar estas mentiras como quieras.

¿Cómo escribiría "un flujo de transferencia para monitorear los bytes" enviados? Si hace algún tipo de diferencia, estoy tratando de hacer esto para impulsar las cargas de imágenes desde el navegador a Cloudinary .

NOTA : No estoy interesado en la biblioteca Cloudinary JS , ya que depende de jQuery y mi aplicación no. Solo estoy interesado en el procesamiento de flujo necesario para hacer esto con javascript nativo y el polyfill de fetch de Github.

https://fetch.spec.whatwg.org/#fetch-api



Las transmisiones están comenzando a llegar a la plataforma web ( https://jakearchibald.com/2016/streams-ftw/ ) pero aún es pronto.

Pronto podrá proporcionar una secuencia como el cuerpo de una solicitud, pero la pregunta abierta es si el consumo de esa secuencia se relaciona con los bytes cargados.

Las redirecciones particulares pueden provocar que los datos se retransmitan a la nueva ubicación, pero las transmisiones no pueden "reiniciarse". Podemos solucionar esto convirtiendo el cuerpo en una devolución de llamada que se puede llamar varias veces, pero debemos asegurarnos de que exponer el número de redireccionamientos no es una pérdida de seguridad, ya que sería la primera vez en la plataforma que JS podría Detecta eso.

Algunos se preguntan si incluso tiene sentido vincular el consumo de flujo a los bytes cargados.

Larga historia corta: esto aún no es posible, pero en el futuro esto será manejado ya sea por secuencias o algún tipo de devolución de llamada de nivel superior pasado a fetch() .


Mi solución es usar axios , que lo soporta bastante bien:

axios.request( { method: "post", url: "/aaa", data: myData, onUploadProgress: (p) => { console.log(p); //this.setState({ //fileprogress: p.loaded / p.total //}) } }).then (data => { //this.setState({ //fileprogress: 1.0, //}) })

Tengo un ejemplo para usar esto en reaccionar en github.


No creo que sea posible. El borrador dice:

actualmente carece [ en comparación con XHR ] cuando se trata de solicitar progresión

(respuesta anterior):
El primer ejemplo en el https://fetch.spec.whatwg.org/#fetch-api da una idea de cómo:

Si desea recibir los datos del cuerpo progresivamente:

function consume(reader) { var total = 0 return new Promise((resolve, reject) => { function pump() { reader.read().then(({done, value}) => { if (done) { resolve() return } total += value.byteLength log(`received ${value.byteLength} bytes (${total} bytes in total)`) pump() }).catch(reject) } pump() }) } fetch("/music/pk/altes-kamuffel.flac") .then(res => consume(res.body.getReader())) .then(() => log("consumed the entire body without keeping the whole thing in memory!")) .catch(e => log("something went wrong: " + e))

Además del uso del antipatrón del constructor Promise , puede ver esa response.body es un flujo desde el que puede leer byte a byte utilizando un lector, y puede activar 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 bastante terminada, y no tengo idea de si esto ya funciona en alguna implementación de recuperación.


Una posible solución sería utilizar el new Request() constructor new Request() luego verificar Boolean atributo Boolean Request.bodyUsed

El bodyUsed atributo bodyUsed debe devolver verdadero si está disturbed , y falso de lo contrario.

para determinar si se distributed secuencia

Se dice que un objeto que implementa la mezcla del Body se disturbed si el body no es nulo y se disturbed su stream .

Devuelve la Promise fetch() desde dentro .then() encadenada a la llamada recursiva .read() de un ReadableStream cuando Request.bodyUsed es igual a true .

Tenga en cuenta que el enfoque no lee los bytes de Request.body ya que los bytes se transmiten al punto final. Además, la carga podría completarse mucho antes de que cualquier respuesta se devuelva por completo al navegador.

const [input, progress, label] = [ document.querySelector("input") , document.querySelector("progress") , document.querySelector("label") ]; const url = "/path/to/server/"; input.onmousedown = () => { label.innerHTML = ""; progress.value = "0" }; input.onchange = (event) => { const file = event.target.files[0]; const filename = file.name; progress.max = file.size; const request = new Request(url, { method: "POST", body: file, cache: "no-store" }); const upload = settings => fetch(settings); const uploadProgress = new ReadableStream({ start(controller) { console.log("starting upload, request.bodyUsed:", request.bodyUsed); controller.enqueue(request.bodyUsed); }, pull(controller) { if (request.bodyUsed) { controller.close(); } controller.enqueue(request.bodyUsed); console.log("pull, request.bodyUsed:", request.bodyUsed); }, cancel(reason) { console.log(reason); } }); const [fileUpload, reader] = [ upload(request) .catch(e => { reader.cancel(); throw e }) , uploadProgress.getReader() ]; const processUploadRequest = ({value, done}) => { if (value || done) { console.log("upload complete, request.bodyUsed:", request.bodyUsed); // set `progress.value` to `progress.max` here // if not awaiting server response // progress.value = progress.max; return reader.closed.then(() => fileUpload); } console.log("upload progress:", value); progress.value = +progress.value + 1; return reader.read().then(result => processUploadRequest(result)); }; reader.read().then(({value, done}) => processUploadRequest({value,done})) .then(response => response.text()) .then(text => { console.log("response:", text); progress.value = progress.max; input.value = ""; }) .catch(err => console.log("upload error:", err)); }


const req = await fetch(''./foo.json''); const total = Number(req.headers.get(''content-length'')); let loaded = 0; for await(const {length} of req.body.getReader()) { loaded = += length; const progress = ((loaded / total) * 100).toFixed(2); // toFixed(2) means two digits after floating point console.log(`${progress}%`); // or yourDiv.textContent = `${progress}%`; }


const response = await fetch(url); const total = Number(response.headers.get(''content-length'')); const reader = response.body.getReader(); let bytesReceived = 0; while (true) { const result = await reader.read(); if (result.done) { console.log(''Fetch complete''); break; } bytesReceived += result.value.length; console.log(''Received'', bytesReceived, ''bytes of data so far''); }

gracias a este enlace: https://jakearchibald.com/2016/streams-ftw/