Téléchargement progressif avec fetch ()

Fetch est une API propre aux navigateurs qui permet de présenter des requêtes à un serveur HTTP par voie de programmation, autrement dit depuis du code JavaScript.
Fetch remplace XMLHttpRequest, dont elle est une version plus moderne. En particulier :
  • XMLHttpRequest est bien une API asynchrone, mais elle repose sur le recours à des callbacks. Or ECMAScript 2015 a introduit les promesses pour faciliter la programmation asynchrone en échappant au "callback hell", mais XMLHttpRequest n'en tient pas compte.
  • Du fait de Same-Origin Policy (SOP), XMLHttpRequest ne permet pas de récupérer une ressource dont l'origine est différente de celle de la page. Or SOP a été tempérée en introduisant Cross-Origin Resource Sharing (CORS), mais XMLHttpRequest n'en tient pas compte.
Pour se familiariser avec Fetch, l'on se propose d'écrire une API qui permet de récupérer une série de ressources tout en étant tenu informé de la progression du téléchargement de chacune.
Suivi de la progression de téléchargements simultanés avec fetch ()
Le code JavaScript devra être aussi simple que possible, mais on n'échappera pas à la mobilisation de quelques concepts fondamentaux : les promesses, la récursivité, les closures, etc. Pas d'affolement, tout est expliqué en détail !
Continuer la lecture de "Téléchargement progressif avec fetch ()"
Téléchargement progressif avec fetch ()

CORS avec Node.js

Pour faire face à la montée des menaces sur leurs utilisateurs, les navigateurs se sont au fil du temps enrichis de mécanismes qui visent à contrôler le contenu d'une page Web. En particulier, il faut évoquer :
CORS avec Node.js
Du fait qu'il ne fallait pas casser le Web en instaurant ces mécanismes, ces derniers ne changent pas grand-chose pour le développeur d'une application Web standard, au sens d'un ensemble de pages servies par un même serveur, qui n'affichent jamais que du contenu qui en provient.
C'est tout particulièrement vrai pour CSP, qui ne vient pas limiter des pratiques telles comme par exemple du script inline dans une balise <script>, tant que le développeur ne met pas lui-même en place CSP en accompagnant ses pages d'un header Content-Security-Policy.
Il est va autrement pour SOP et CORS, qui d'emblée limitent des pratiques. En particulier, il est impossible depuis le script d'une page Web de formuler une requête via l'API Fetch pour récupérer du contenu dont l'origine, entendue comme la composition du nom de domaine et du numéro de port, n'est pas celle de la page en question.
Or cela peut être nécessaire. Illustration avec une application Web où l'utilisateur accède à une page servie par un serveur Node.js (module http) à l'écoute sur le port 3000 de localhost, dans laquelle un script récupère du contenu en appelant un service exposé par un autre serveur Node.js (module http) à l'écoute sur le port 3001 du même localhost.
Continuer la lecture de "CORS avec Node.js"
CORS avec Node.js

Chaîner les promesses en JavaScript

Comme cela a été expliqué dans cet article, l'intérêt des promesses en JavaScript, c'est de permettre au développeur de pratiquer l'asycnhronisme sans tomber dans le "callback hell".
Pour autant, cela suppose de bien comprendre le fonctionnement de ce mécanisme alternatif, tout particulièrement cet aspect essentiel qu'est l'enchaînement, ou le chaînage, de promesses.
Pratique du chaînage de promesses en JavaScript
En cette matière, un examen trop superficiel du mécanisme peut conduire à s'en faire une idée fausse, et de là mal pratiquer le chaînage de promesses via .then () et .catch ().
Pour vous permettre d'honorer vos promesses, voici quelques éclaircissements pratiques...
Continuer la lecture de "Chaîner les promesses en JavaScript"
Chaîner les promesses en JavaScript

Déboguer les promesses en JavaScript

Le développeur adepte du débogueur de Firefox qui s'initie à la programmation asynchrone à l'aide de promesses de JavaScript peut assez rapidement en venir à s'arracher les cheveux.
En effet, le débogueur lui semblera parfois ne pas afficher des exceptions de syntaxe. Dur de localiser une erreur dans l'écriture du code et de la corriger dans ces conditions...
Déboguer les promesses en JavaScript
Cela tient à la manière assez particulière dont ce type d'exception est géré par le débogueur. Fort heureusement, il existe une solution technique... pour autant que l'on veille bien à la mettre en oeuvre !
Continuer la lecture de "Déboguer les promesses en JavaScript"
Déboguer les promesses en JavaScript

Executer une file de tâches asynchrones en JavaScript

Depuis l'introduction des promesses puis du sugar coating qui permet d'en faciliter l'usage, tout développeur JavaScript se doit de maîtriser l'art de la programmation asynchrone. Ce sera tout particulièrement le cas s'il souhaite s'investir dans Node.js, où toute fonction devrait en théorie pouvoir être exécutée de manière asynchrone.
Cela implique de repenser la manière de programmer les choses les plus simples. Par exemple, purger à l'infini une file (FIFO) de tâches asynchrones. Dans le monde asynchrone, il est inconcevable d'écrire une boucle où serait logé le programme principal, au seul prétexte de pouvoir régulièrement consulter l'état de la file et exécuter une tâche, s'il en reste, quand l'exécution de la précédente, s'il y en avait, s'est achevée. En un mot, il est hors de question de faire du polling.
Interface pour exécuter une file de tâches asynchrones
Comment faire ? C'est très simple, et cela constitue un excellent exemple pour s'initier à la programmation asynchrone en JavaScript. Explications dans ce qui suit.
Continuer la lecture de "Executer une file de tâches asynchrones en JavaScript"
Executer une file de tâches asynchrones en JavaScript

Boucle d’événements et multithreading dans Node.js

En un peu plus d'une dizaine d'années, Node.js s'est imposé comme un élément central des architectures Web. A en lire des articles inventoriant les grandes entreprises qui l'utilisent, comme ici, Node.js est utilisé par Netflix, eBay, PayPal, et j'en passe.
Node.js
Joli succès pour cette technologie sortie de l'esprit de Ryan Dahl, qui a su repenser "out of the box" une manière de fonctionner des serveurs HTTP que plus personne ou presque n'interrogeait, se reposant dessus comme sur un acquis.
Pourtant, en dépit de sa popularité, il apparaît que les bases du fonctionnement de Node.js sont très mal maîtrisées. Au coeur du sujet : le fonctionnement de la boucle d'événements, et la place qu'elle laisse au multithreading.
Retour à base, pour tenter de comprendre non seulement ces aspects, mais aussi les raisons pour lesquelles ils peuvent être encore méconnus.
Continuer la lecture de "Boucle d’événements et multithreading dans Node.js"
Boucle d’événements et multithreading dans Node.js

Déboguer facilement un service Web en PHP et JavaScript

S'il vous en reste, le développement d'un service Web en JavaScript (côté client) et PHP (côté serveur) est une bonne occasion de vous arracher des cheveux. Le débogage est une opération délicate, quand vous ne pouvez pas vous appuyer sur un système tel que Xdebug.
C'est que dans une application Web traditionnelle, un appel de service consiste simplement à appeler un script PHP dont le contenu est retourné par le serveur. Dès lors, toute erreur survenant lors de l'exécution du service s'affiche nécessairement à l'écran.
Il en va tout autrement dans le cas d'une application Web moderne, de type Progressive Web Application. Ici, l'appel de service s'effectue par le truchement d'un objet XMLHttpRequest. Le résultat de l'exécution du script est toujours renvoyé par le serveur, mais il parvient au client via une des propriétés de cet objet.
Dans ces conditions, la callback fournie à l'objet XMLHttpRequest doit analyser ce résultat pour déterminer si une erreur ou non a été rencontrée, et si oui remonter au développeur toutes les informations utiles qu'il voyait s'afficher à l'écran dans le cas d'une application Web traditionnelle : chemin d'accès au script, ligne dans le script où l'erreur est survenue, description de l'erreur, voire plus.
Déboguer facilement un service en JavaScript et PHP
La première chose à faire avant de se lancer dans le développement d'un service Web consiste donc à mettre en place une système de remontée des résultats d'un appel de service efficace. On aurait tort de s'en passer, car il ne faut finalement guère de lignes de code.
Continuer la lecture de "Déboguer facilement un service Web en PHP et JavaScript"
Déboguer facilement un service Web en PHP et JavaScript

Afficher du texte en gros pixels dans une page Web

Pas facile de la jouer rétro avec les technologies du jour ! Afficher un texte en gros pixels comme sur les vieilles bécanes, c'est toute une affaire quand on sait que le moindre texte subit désormais de multiples traitements pour le rendre bien lisible à l'écran. En particulier, ses courbes sont lissées en recourant à l'anti-aliasing.
L'anti-aliasing: voilà l'ennemi. On connaît quelques contournements mis en place pour tenir compte du revival des jeux à gros pixels. Sur ce blog, cet article montre comment désactiver l'anti-aliasing dans le contexte 2D du canvas.
Toutefois, ce contournement ne fonctionne que dans le cas de la copie d'une image et le dessin de formes simples - le rectangle. L'API Canvas ne propose rien pour afficher un texte en gros pixels dans une police donnée, une police de 8x8 pixels à l'ancienne qui plus est.
Dès lors, comment parvenir à produire un pareil résultat ?
La page d'accueil de Pixel Saga: du texte pixelisé généré automatiquement
La solution est très simple. C'est tout simplement celle qui était en vigueur sur les vieux coucous... Explications.
Continuer la lecture de "Afficher du texte en gros pixels dans une page Web"
Afficher du texte en gros pixels dans une page Web

Web Components : un élément <TR> personnalisé (2/2)

Cet article est le second, et donc le dernier, d'un série de deux consacrés à la réalisation d'un élément <tr> personnalisé exploitant des technologies de la famille Web Components.
Dans le premier article, il s'agissait de passer en revue l'intégralité du code requis pour créer un élément <tr> personnalisé <param-number> permettant d'ajouter un spinner précédé d'un libellé dans un tableau, comme ici :
Un élément personnalisé
Ce spinner est lié à une propriété quelconque que le développeur pointe à l'élément personnalisé en fournissant un chemin d'accès, comme par exemple shader.particle.start.delay. Ainsi, une fois qu'il a rajouté un élément <param-number> dans la page Web, le développeur n'a plus qu'à réagir aux modifications de la propriété via son getter. Le chemin est réévalué à chaque accès, si bien que le développeur peut toujours changer l'objet sur lequel il débouche.
Dans ce second article, il s'agit de revenir sur certains choix techniques qui ont présidé à l'écriture du code de l'élément personnalisé. En particulier, on s'interroge sur les avantages et les inconvénients d'une personnalisation d'un élément HTML existant tel que <tr>. Il s'agit aussi de pointer quelques enjeux des technologies de la famille Web Components pour l'avenir, notamment le recours aux classes en JavaScript et la prise de distance avec les éléments HTML standards.
Continuer la lecture de "Web Components : un élément <TR> personnalisé (2/2)"
Web Components : un élément <TR> personnalisé (2/2)

Web Components : un élément <TR> personnalisé (1/2)

Web Components est un ensemble de technologies apparues dans le cadre de HTML5 : custom elements, templates et shadow DOM - les imports HTML aussi, mais ils ne sont toujours pas standardisés. D'après Can I use... (ici, ici et ), ces technologies sont désormais assez largement adoptées dans leurs dernières versions - la v1. En particulier, Firefox gère parfaitement cela depuis l'automone dernier - la version 63.
Pour faire court, cet ensemble permet de créer un élément ou une variante d'élément HTML dans une page Web, et de faire exécuter du code JavaScript au moment où le navigateur cherche à l'interpréter, ce qui permet d'injecter dans la page Web ce que vous voulez. Par exemple, on peut écrire... :
<param-number name="Delay" property="g.shaderUI.delay" step="1" iseditable="true" buttonclassname="uiButton" numberclassname="uiNumber" layout="middle"></param-number>
...et récupérer une référence sur cet élément au moment où le navigateur cherche quoi en faire. Ici, il serait possible d'afficher un champ de saisie entouré de deux boutons, l'un pour décrémenter et l'autre pour incrémenter la valeur figurant dans le champ :
Un élément personnalisé
On comprend qu'il serait alors facile d'utiliser un tel composant à volonté, comme par exemple ici :
Une page Web utilisant généreusement des éléments personnalisés
Mais il pourrait tout autant s'agir d'effectuer une requête asynchrone à une base de données - une bonne occasion d'utiliser une promise -, afin de récupérer des informations sur un client et de les afficher quand elles sont disponibles, sans bloquer l'affichage du reste de la page - soyons progressifs.
Le sujet des Web Components est bien documenté sur MDN, et la spécification HTML qui doit servir de référence est pour sa part assez claire. Pourquoi en parler alors ?
Il faut en parler, car le sujet reste assez nouveau, et car la pratique montre que le développeur peut être confronté à des choix assez cornéliens. L'exemple pris ici est celui de la création d'un élément custom pour rajouter des lignes à un tableau. Ce sujet s'impose de lui-même dès que l'on commence à manipuler les Web Components, car la première idée qu'on y voit est de factoriser des éléments redondants, à ce titre souvent affichés dans un tableau.
Cet article est le premier d'un série de deux. Il s'agit de présenter l'intégralité du code requis pour faire fonctionner l'élément <param-number> évoqué. Dans le second article, plusieurs choix techniques et perspectives des technologies utilisées feront l'objet d'une discussion.
Continuer la lecture de "Web Components : un élément <TR> personnalisé (1/2)"
Web Components : un élément <TR> personnalisé (1/2)