ajax - example - ¿Cómo escribir javascript en el lado del cliente para recibir y analizar la respuesta `chunked` a tiempo?
carga asincrona javascript (3)
Pronto deberíamos poder usar la API ReadableStream
( documentos MDN aquí ). El siguiente código parece estar funcionando con la versión de Chrome 62.0.3202.94:
fetch(url).then(function (response) {
let reader = response.body.getReader();
let decoder = new TextDecoder();
return readData();
function readData() {
return reader.read().then(function ({value, done}) {
let newData = decoder.decode(value, {stream: !done});
console.log(newData);
if (done) {
console.log(''Stream complete'');
return;
}
return readData();
});
}
});
Estoy usando Play Framework, para generar una respuesta fragmentada. El código es:
class Test extends Controller {
public static void chunk() throws InterruptedException {
for (int i = 0; i < 10; i++) {
String data = repeat("" + i, 1000);
response.writeChunk(data);
Thread.sleep(1000);
}
}
}
Cuando uso el navegador para visitar http://localhost:9000/test/chunk
, puedo ver los datos que se muestran aumentados cada segundo. Pero, cuando escribo una función de JavaScript para recibir y manejar los datos, descubro que bloqueará hasta que todos los datos recibidos.
El código es:
$(function(){
$.ajax(
"/test/chunked",
{
"success": function(data, textStatus, xhr) {
alert(textStatus);
}
}
);
});
Puedo ver un cuadro de mensaje emergente después de 10s, cuando todos los datos recibidos.
¿Cómo obtener la transmisión y manejar los datos a tiempo?
el evento de success
se activará cuando se complete la transmisión de datos y la conexión se cierre con un código de respuesta de 200. Creo que deberías ser capaz de implementar un evento nativo onreadystatechanged
y ver los paquetes de datos tal como vienen.
jQuery no es compatible con eso, pero puede hacerlo con XHR normal:
var xhr = new XMLHttpRequest()
xhr.open("GET", "/test/chunked", true)
xhr.onprogress = function () {
console.log("PROGRESS:", xhr.responseText)
}
xhr.send()
Esto funciona en todos los navegadores modernos , incluida la especificación IE 10. W3C here .
La desventaja aquí es que xhr.responseText
contiene una respuesta acumulada. Puede usar subcadena en él, pero una mejor idea es usar el atributo responseType y usar slice
en un ArrayBuffer
.