Passer au contenu principal





Mise à jour

Chrome 85 a une implémentation expérimentale des flux de requêtes, ce qui signifie que vous pouvez commencer à faire une requête avant que le corps complet ne soit disponible.

Vous pouvez l'utiliser pour :

  • Calienta el serveur. En otras palabras, puede iniciar la solicitud una vez que el Nom d'utilisateur enfoca un campo de entrada de texto y quitar todos los en-têtes, luego esperar hasta que el usuario presione ‘enviar’ antes de enviar los datos que ingresaron.
  • Envíe gradualmente datos generados en el client, como audio, video o datos de entrada.
  • Recrea los sockets la toile à travers de HTTP.

Mais comme il s'agit d'une fonction de plate-forme Web de bas niveau, ne vous limitez pas à moi idées. Vous pouvez peut-être penser à un cas d'utilisation beaucoup plus intéressant pour le streaming de requêtes.

Tester les flux de requêtes

Activer le support lors de la phase de preuve d'origine

Les flux de requêtes de récupération sont disponibles dans un test d'origine à partir de Chrome 85. Le test d'origine devrait se terminer dans Chrome 87.

Les tests d'origine vous permettent de tester de nouvelles fonctionnalités et de fournir des commentaires sur leur convivialité, leur caractère pratique et leur efficacité à la communauté des normes Web. Pour plus d'informations, consultez le Guide de test d'origine pour les développeurs Web. Pour vous inscrire à cette preuve d'origine ou à toute autre preuve d'origine, visitez le page d'inscription.

Inscrivez-vous pour obtenir une preuve d'origine

  1. Demander un jeton par votre origine.
  2. Ajoutez le jeton à vos pages. Il y a deux façons de le faire:
    • Ajouter un origine-procès balise à l'en-tête de chaque page. Par exemple, cela pourrait ressembler à ceci:
    • Si vous pouvez configurer votre serveur, vous pouvez également ajouter le jeton à l'aide d'un Essai d'origine En-tête HTTP. L'en-tête de réponse qui en résulte doit ressembler à ceci:
      Essai d'origine: TOKEN_GOES_HERE

Activation via chrome: // flags

Testez les flux de requêtes dans Chrome 85 en activant un indicateur expérimental :
activer les fonctionnalités expérimentales de la plate-forme Web.

Manifestation

Cela montre comment vous pouvez transmettre des données de l'utilisateur au serveur et envoyer des données qui peuvent être traitées en temps réel.

Ouais, d'accord, ce n'est pas l'exemple le plus imaginatif, je voulais juste que ce soit simple, d'accord ?

Quoi qu'il en soit, comment cela fonctionne-t-il ?

Précédemment dans les aventures passionnantes de fetch streams

Répondre Las transmisiones han estado disponibles en todos los navigateurs modernos durante un tiempo. Le permiten acceder a partes de una respuesta a medida que llegan del servidor:

const response = attendre aller chercher(URL);
const lecteur = response.corps.getReader();

tandis que (vrai) {
const { valeur, Fini } = attendre lecteur.read();
si (Fini) break;
console.Journal('Received', valeur);
}

console.Journal('Response fully received');

Chaque valeur c'est un Uint8Array d'octets. Le nombre de tableaux que vous obtenez et la taille des tableaux dépendent de la vitesse du réseau. Si vous disposez d'une connexion rapide, vous obtiendrez moins de "morceaux" de données plus volumineuses. Si vous avez une connexion lente, vous obtiendrez des morceaux plus petits.

Si vous souhaitez convertir les octets en texte, vous pouvez utiliser
TextDecoderou la transmission de transformation la plus récente si votre les navigateurs cibles le supportent:

const response = attendre aller chercher(URL);
const lecteur = response.corps
.pipeThrough(new TextDecoderStream())
.getReader();

TextDecoderStream est un courant de transformation qui rattrape tous ceux Uint8Array
fragments et les transforme en chaînes.

Les flux sont formidables car vous pouvez commencer à agir sur les données au fur et à mesure qu'elles arrivent. Par exemple, si vous recevez une liste de 100 "résultats", vous pouvez afficher le premier résultat dès sa réception, au lieu d'attendre les 100.

Quoi qu'il en soit, ce sont les flux de réponse, la chose nouvelle et passionnante dont je voulais parler est le flux de demande.

Organismes de demande de transmission

Les requêtes peuvent avoir des corps :

attendre aller chercher(URL, {
méthode: 'POST',
corps: requestBody,
});

Auparavant, vous aviez besoin de tout le corps prêt à l'emploi avant de pouvoir lancer la demande, mais maintenant, dans Chrome 85, vous pouvez fournir le vôtre ReadableStream de données :

une fonction wait(milliseconds) {
revenir new Promise((resolve) => setTimeout(resolve, milliseconds));
}

const flux = new ReadableStream({
asynchrone démarrer(controller) {
attendre wait(1000);
controller.enqueue('This ');
attendre wait(1000);
controller.enqueue('is ');
attendre wait(1000);
controller.enqueue('a ');
attendre wait(1000);
controller.enqueue('slow ');
attendre wait(1000);
controller.enqueue('request.');
controller.close();
},
}).pipeThrough(new TextEncoderStream());

aller chercher(URL, {
méthode: 'POST',
en-têtes: { 'Content-Type': 'text/plain' },
corps: flux,
});

Ce qui précède enverra "Ceci est une requête lente" au serveur, un mot à la fois, avec une pause d'une seconde entre chaque mot.

Chaque partie du corps d'une demande doit être un Uint8Array d'octets, donc j'utilise
pipeThrough(nouveau TextEncoderStream()) para hacer la conversion por mí.

flux enregistrables

Parfois, il est plus facile de travailler avec des flux lorsque vous avez un WritableStream. Vous pouvez le faire en utilisant un flux "d'identité", qui est une paire lisible/inscriptible qui prend tout ce qui est passé à votre extrémité d'écriture et l'envoie à l'extrémité de lecture. Vous pouvez en créer un en créant un TransformStream sans aucun argument :

const { lisible, inscriptible } = new TransformStream();

const réponsePromise = aller chercher(URL, {
méthode: 'POST',
corps: lisible,
});

Désormais, tout ce que vous envoyez au flux d'écriture fera partie de la requête. Cela vous permet de composer des flux ensemble. Par exemple, voici un exemple idiot où les données sont extraites d'une URL, compressées et envoyées à une autre URL :


const response = attendre aller chercher(url1);
const { lisible, inscriptible } = new TransformStream();


response.corps
.pipeThrough(new CompressionStream('gzip'))
.pipeTo(inscriptible);


attendre aller chercher(url2, {
méthode: 'POST',
corps: lisible,
});

L'exemple ci-dessus utilise flux de compression pour compresser des données arbitraires à l'aide de gzip.

Détection des fonctionnalités

Si proporciona un objeto de cuerpo que el le navigateur no maneja específicamente, llamará toString() dans l'objet et utiliser le résultat comme corps. Si le navigateur ne prend pas en charge les flux de requêtes, cela signifie que le corps de la requête devient
"[objet ReadableStream]" – probablemente no être lo que desea enviar al servidor. Para evitar esto, use la detección de características:

const supportsRequestStreams = !new Demander('', {
corps: new ReadableStream(),
méthode: 'POST',
}).en-têtes.Avez-vous('Content-Type');

si (supportsRequestStreams) {
} else {
}

Cela fonctionne parce que le navigateur ajoute un Type de contenu en-tête de
text/plain;charset=UTF-8 à la requête si le corps est du texte. Le navigateur ne traite le corps comme du texte que si non prend en charge les flux de demandes, sinon il n'ajoutera pas de Type de contenu en-tête du tout.

restriction

Les requêtes de streaming sont un nouveau pouvoir sur le Web, elles s'accompagnent donc de quelques restrictions :

redirections restreintes

Algunas formas de redireccionamiento HTTP requieren que el navegador vuelva a enviar el cuerpo de la solicitud a otra URL. Para admitir esto, el navegador tendría que almacenar en búfer el Contenu de la transmisión, lo que anula el punto, por lo que no hace eso.

En cambio, si la solicitud tiene un cuerpo de transmisión y la respuesta es una réorienter HTTP distinta de 303, la recuperación se rechazará y la redirección non être suivi.

Les redirections 303 sont autorisées, car elles modifient explicitement la méthode pour OBTENIR et supprimez le corps de la requête.

HTTP/2 uniquement par défaut

Par défaut, la récupération sera refusée si la connexion n'est pas HTTP/2. Si vous souhaitez utiliser des requêtes de streaming sur HTTP/1.1, vous devez vous inscrire :

attendre aller chercher(URL, {
méthode: 'POST',
corps: flux,
allowHTTP1ForStreamingUpload: vrai,
});

Mise en garde:
allowHTTP1ForStreamingUpload il n'est pas standard et ne sera utilisé que dans le cadre de la mise en œuvre expérimentale de Chrome.

Selon les règles HTTP/1.1, les corps de requête et de réponse doivent envoyer un
Contenu-Longueur l'en-tête, afin que l'autre côté sache combien de données il recevra, ou modifier le format du message à utiliser codage fragmenté. Avec l'encodage fragmenté, le corps est divisé en parties, chacune avec sa propre longueur de contenu.

L'encodage Chunky est assez courant lorsqu'il s'agit de HTTP/1.1 réponses, mais très rare quand il s'agit de demandes. Pour cette raison, Chrome est un peu préoccupé par la compatibilité, il est donc activé pour le moment.

Ce n'est pas un problème pour HTTP/2, puisque les données HTTP/2 sont toujours « fragmentées », même si elles appellent des fragments
cadres. Le codage Chunky n'a pas été introduit avant HTTP/1.1, donc les requêtes avec des corps de flux échoueront toujours sur les connexions HTTP/1.

Selon le déroulement de ce test, la spécification limitera les réponses en continu à HTTP/2 ou l'autorisera toujours à la fois pour HTTP/1.1 et HTTP/2.

Pas de communication duplex

Une fonctionnalité peu connue de HTTP (bien que le fait qu'il s'agisse d'un comportement standard dépend de la personne à qui vous demandez) est que vous pouvez commencer à recevoir la réponse tout en envoyant la requête. Cependant, il est si peu connu qu'il n'est pas bien pris en charge par les serveurs et, bien, les navigateurs.

Dans l'implémentation actuelle de Chrome, vous n'obtiendrez la réponse qu'après l'envoi complet du corps. Dans l'exemple suivant réponsePromise il ne sera pas résolu tant que le flux lisible n'aura pas été fermé. Tout ce que le serveur envoie avant ce point sera mis en mémoire tampon.

const réponsePromise = aller chercher(URL, {
méthode: 'POST',
corps: readableStream,
});

La deuxième meilleure option pour une communication en duplex intégral consiste à effectuer une recherche avec une demande de diffusion, puis à effectuer une nouvelle recherche pour recevoir la réponse de diffusion. Le serveur aura besoin d'un moyen d'associer ces deux requêtes, comme un ID dans l'URL. C'est ainsi que fonctionne la démo.

Problèmes potentiels

Ouais, donc... c'est une nouvelle fonctionnalité, et elle n'est pas beaucoup utilisée sur Internet ces jours-ci. Voici quelques problèmes à prendre en compte :

Incompatibilité côté serveur

Certains serveurs d'applications ne prennent pas en charge les demandes de diffusion en continu, mais attendent que la demande complète soit reçue avant de vous permettre de regarder quoi que ce soit, ce qui va à l'encontre du but. Utilisez plutôt un serveur d'applications prenant en charge le streaming, tel que
NodeJSName.

Mais vous n'êtes pas encore tiré d'affaire ! Le serveur d'application, tel que NodeJS, est généralement derrière un autre serveur, souvent appelé "serveur frontal", qui lui-même peut être derrière un CDN. Si l'un d'eux décide de mettre la requête en mémoire tampon avant de la transmettre au serveur suivant de la chaîne, il perdra le bénéfice de la diffusion en continu des requêtes.

De plus, si vous utilisez HTTP/1.1, l'un des serveurs peut ne pas être prêt pour l'encodage fragmenté et peut échouer avec une erreur. Mais bon, vous pouvez au moins essayer cela et essayer de changer de serveur si nécessaire.

... longue respiration ...

Incompatibilité indépendante de votre volonté

Si está utilizando HTTPS, no necesita preocuparse por los proxies entre usted y el usuario, pero el usuario puede estar ejecutando un proxy en su máquina. Algún Logiciel de protección de Internet hace esto para permitirle monitorear todo lo que ocurre entre el navegador y la red.

Il peut y avoir des cas où ce logiciel met en mémoire tampon les corps de requête, ou dans le cas de HTTP/1.1, ne vous attendez pas à un encodage volumineux et il se casse d'une manière intéressante.

À l'heure actuelle, on ne sait pas à quelle fréquence, le cas échéant, cela se produira.

Si vous voulez vous prémunir contre cela, vous pouvez créer un "test de fonctionnalité" similaire à la démo ci-dessus, où vous essayez de diffuser des données sans fermer le flux. Si le serveur reçoit les données, il peut répondre via une recherche différente. Une fois que cela se produit, vous savez que le client prend en charge les demandes de streaming de bout en bout.

commentaires bienvenus

Los comentarios de la comunidad son cruciales para el diseño de nuevas API, así que pruébelo y díganos lo que piensa. Si encuentra algún error, por favor signalez-les, mais si vous avez des commentaires généraux, veuillez les envoyer à Groupe Google blink-network-dev.

photo par Laura Lefurgey-Smith
au
Unsplash