Yo estoy luchando para encontrar la documentación o ejemplos de la aplicación de una carga indicador de progreso mediante fetch.

Esta es la única referencia que he encontrado hasta ahora, que establece:

Eventos de progreso son una característica de alto nivel que no llegará en buscar ahora. Usted puede crear su propio mirando el Content-Length encabezado y el uso de un paso de corriente para controlar los bytes recibidos.

Esto significa que usted puede gestionar de forma explícita respuestas sin un Content-Length de manera diferente. Y, por supuesto, incluso si Content-Length es que puede ser una mentira. Con los arroyos que usted puede manejar estas mentiras sin embargo que usted desea.

Cómo iba yo a escribir «un paso de flujo para controlar la bytes» enviado? Si se hace cualquier tipo de diferencia, yo estoy tratando de hacer esto al poder de la imagen de carga del navegador a Cloudinary.

NOTA: estoy no interesados en la Cloudinary JS biblioteca, ya que depende de jQuery y mi aplicación no. Sólo estoy interesado en la secuencia de procesamiento necesario para hacer esto con javascript nativas y de Github fetch polyfill.


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

InformationsquelleAutor neezer | 2016-02-29

8 Comentarios

  1. 32

    Arroyos están empezando a aterrizar en la plataforma web ( https://jakearchibald.com/2016/streams-ftw/ ), pero aún es temprano días.

    Pronto vas a ser capaz de proporcionar un flujo como el cuerpo de una petición, pero la pregunta abierta es si el consumo de corriente que se refiere a los bytes cargados.

    Particular redirige puede resultar en datos retransmitidos a la nueva ubicación, pero los ríos no puede «reiniciar». Podemos arreglar esto, girando el cuerpo en una devolución de llamada que puede ser llamado varias veces, pero tenemos que estar seguros de que la exposición de el número de redirecciones no es una seguridad de fuga, ya que sería la primera vez en la plataforma JS podría detectar que.

    Que algunos se pregunten si tiene sentido vincular corriente de consumo de bytes cargados.

    Larga historia corta: esto no es posible aún, pero en el futuro esto será manejado por los arroyos, o algún tipo de alto nivel de devolución de llamada pasa a fetch().

    • Demasiado malo. La aceptación de esta por ahora, pero cuando esto se convierte en una realidad, espero que alguien más va a publicar una solución actualizada! 🙂
    • alguna novedad?
    • Actualización – mostrando el progreso con la captura de la API a través de secuencias – twitter.com/umaar/status/917789464658890753/photo/1
    • están detrás de la gente pregunta si tiene sentido enlace de corriente consumo de bytes cargados? Acceso Raw siempre ha sido solicitada por los desarrolladores del derecho desde los comienzos de la web días. Los navegadores tienen……
    • ……2 opciones, una es la de otorgar fuerza a los desarrolladores a la gente, y la otra es la de otorgar a los fabricantes de los navegadores de sí mismos a los oligopolios . Las encuestas de la historia muestran que los monopolios no duran siglos pasados. Ya sea que usted trabaje con la gente o la gente va a llegar un día juntos y el derrocamiento de tu mal Googlopoly. Que la gente pregunta si tiene sentido enlace de corriente consumo de bytes cargados?
    • De niza. Será una cosa semejante obra para la carga, por ejemplo, el POST?
    • Pero, la pregunta es sobre el progreso de la carga, no en descargar

  2. 11

    Mi solución es el uso de axios, que apoya esta 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 ejemplo de uso de esta en reaccionar en github.

    • Esa fue mi solución. Axios parece encajar en el molde muy bien.
    • ¿axios Uso fetch o XMLHttpRequest bajo el capó?
    • XMLHttpRequest. Si usted está usando esto para reaccionar nativo, ten en cuenta que XMLHttpRequest parece ser muy, MUY lento para analizar grandes respuestas json cuando se compara con fetch (alrededor de 10 veces más lento, y se congela todo el subproceso de interfaz de usuario).
    • Para obtener el progreso en % this.setState({ fileprogress: Math.round( (p.loaded * 100) / p.total ) })
  3. 7

    Yo no creo que sea posible. El proyecto de los estados:

    es actualmente carecen de [en comparación a XHR] cuando se trata de la solicitud de la progresión de la


    (respuesta anterior):

    El primer ejemplo en la Fetch capítulo de API da una idea sobre cómo :

    Si quieres recibir el cuerpo de datos 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))

    Aparte de su uso de la Promesa constructor antipattern, se puede ver que response.body es una Secuencia de la que se puede leer byte a byte el uso de un Lector, y puede disparar un evento o hacer lo que quieras (por ejemplo, registrar el progreso) para cada una de ellas.

    Sin embargo, la Flujos de especificaciones no parece ser del todo terminado, y no tengo idea de si esto ya funciona en cualquier fetch aplicación.

    • Si he leído que ejemplo correctamente, sin embargo, esto sería para descarga de un archivo a través de fetch. Estoy interesado en los indicadores de progreso para la carga de un archivo.
    • Uy, que cita habla de recepción bytes, lo que me confundió.
    • Nota, Promise constructor no es necesario. Response.body.getReader() devuelve un Promise. Consulte Cómo resolver Uncaught RangeError cuando la descarga de gran tamaño json
    • sí, he fijado en la fuente de la cita ya. Y no, getReader no devuelve una promesa. Ni idea de qué tiene esto que ver con el post enlazado.
    • Sí, estás en lo correcto .getReader()‘s .read() método devuelve un Promise. Que es lo que estaba tratando de transmitir. El enlace es para aludir a la premisa de que si el progreso se puede comprobar para descargar, el progreso puede ser comprobado para subir. Poner juntos un patrón que devuelve el resultado esperado, a un grado apreciable; que es el progreso de fetch() subir. No han encontrado una manera de echo un Blob o File objeto en jsfiddle, probablemente falta algo simple. Las pruebas en localhost uploads de archivos muy rápidamente, sin que imitan las condiciones de la red; aunque acabo de recordar Network throttling.
  4. 4

    Ya que ninguna de las respuestas resolver el problema.

    Sólo para la aplicación de sake, se puede detectar la velocidad de carga de la con algún pequeño fragmento inicial de tamaño conocido y el tiempo de carga puede ser calculada con la longitud de contenido de carga/velocidad. Usted puede usar este tiempo como la estimación.

  5. 3

    Una posible solución sería utilizar new Request() constructor, a continuación, compruebe Request.bodyUsed Boolean atributo

    La bodyUsed atributo del captador debe devolver true si disturbed, y
    false de lo contrario.

    para determinar si el flujo es distributed

    Un objeto que implementa la Body mixin se dice que disturbed si
    body no es null y su stream es disturbed.

    Devolver el fetch() Promise desde dentro .then() encadenado a recursiva .read() llamada de un ReadableStream cuando Request.bodyUsed es igual a true.

    Nota, el enfoque no lee los bytes de la Request.body como los bytes que se transmiten a la estación. También, la carga podría terminar mucho antes de que cualquier respuesta es devuelto en su totalidad para el 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));
    }
  6. 2
    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/

    • Bueno, pero ¿se aplica a la carga como así?
    • Traté de averiguar, pero yo no era capaz de hacerlo. y me gustaría encontrar una manera para hacer esto para subir demasiado.
    • Mismo, pero hasta el momento yo no estaba muy afortunado de encontrar/crear un buen funcionamiento de la carga de ejemplo.
  7. 0
    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}%`;
    }
    • Quiero dar un crédito a Benjamin Gruenbaum para toda la respuesta. Porque he aprendido de su conferencia.
    • Es la conferencia disponible en línea en cualquier lugar? Un enlace a la fuente sería bueno.
    • Aquí es: youtube.com/watch?v=Ja8GKkxahCo (la conferencia fue dada en hebreo)
    • La pregunta es acerca de la carga, no se descarga.

Dejar respuesta

Please enter your comment!
Please enter your name here