Serveur rapide Express js. Node JS et bases d'Express (III)
$ npm installer express
ou, pour avoir accès à la commande express, installez globalement :
$ npm install -g express
Départ rapide
Le moyen le plus simple de démarrer avec Express est d'exécuter la commande express, qui générera l'application :
Création d'une application :
$ npm install -g express $ express /tmp/foo && cd /tmp/foo
Installation des dépendances :
$ npm installer -d
Démarrage du serveur :
Création d'un serveur
Pour créer une instance de express.HTTPServer, appelez simplement la méthode createServer(). Avec notre instance d'application, nous pouvons spécifier des routes basées sur des méthodes HTTP, dans cet exemple app.get() .
var app = require("express").createServer(); app.get("/", function(req, res)( res.send("hello world"); )); app.écouter (3000);
Création d'un serveur HTTPS
Pour initialiser express.HTTPSServer , nous effectuons les mêmes étapes que ci-dessus, mais nous transmettons également un objet options contenant la clé, le certificat et d'autres paramètres décrits dans la documentation du module https NodeJS.
var app = require("express").createServer(( clé : ... ));
Configuration
Express prend en charge les environnements arbitraires, tels que la production et le développement. Les développeurs peuvent utiliser la méthode configure() pour ajouter les fonctionnalités nécessaires à un environnement donné. Lorsque configure() est appelé sans nom d'environnement, il se déclenchera dans n'importe quel environnement avant que toute configuration dans laquelle l'environnement est spécifié ne se déclenchera.
Dans l'exemple ci-dessous, nous utilisons simplement l'option dumpExceptions et, en mode développement, répondons au client avec une trace de pile de l'exception. Dans les deux modes, nous utilisons les couches methodOverride et bodyParser. Notez l'utilisation de app.router , qui lui-même permet de monter les routes - sinon elles sont montées la première fois que app.get() , app.post() , etc. sont appelées.
app.configure(function())( app.use(express.methodOverride()); app.use(express.bodyParser()); app.use(app.router); )); app.configure("development", function())( app.use(express.static(__dirname + "/public")); app.use(express.errorHandler(( dumpExceptions: true, showStack: true ))); ) ); app.configure("production", function())( var oneYear = 31557600000; app.use(express.static(__dirname + "/public", ( maxAge: oneYear ))); app.use(express.errorHandler() ) ; ));
Pour les environnements avec des paramètres similaires, vous pouvez transmettre plusieurs noms d'environnement :
app.configure("stage", "prod", function())( // config ));
Pour les paramètres internes et arbitraires, Express a les méthodes set(key[, val]) , enable(key) , Disable(key) :
app.configure(function () ( app.set("views", __dirname + "/views"); app.set("views"); // => "/absolute/path/to/views" app.enable ("une fonctionnalité"); // identique à app.set("une fonctionnalité", true); app.disable("une fonctionnalité"); // identique à app.set("une fonctionnalité", false) ; .enabled("une fonctionnalité") // => false ));
Pour définir l'environnement, nous pouvons définir la variable d'environnement NODE_ENV. Par exemple:
$ NODE_ENV=nœud de production app.js
Ceci est très important car de nombreux mécanismes de mise en cache ne sont activés que dans un environnement de production.
Paramètres
Prêt à l'emploi, Express prend en charge les paramètres suivants :
- home est le chemin de base de l'application, qui est utilisé pour res.redirect() ainsi que pour la prise en charge transparente des applications montées.
- vues est le répertoire racine des vues. Par défaut dossier_actuel/vues
- moteur de vue - moteur de modèle par défaut pour les vues appelées sans extension de fichier.
- options d'affichage - un objet reflétant les options d'affichage globales
- view cache - activer la mise en cache des vues (activé dans l'environnement de production)
- routes sensibles à la casse - activer les routes sensibles à la casse
- routage strict - si activé, les barres obliques finales ne sont plus ignorées
- jsonp callback - autoriser la méthode res.send() à prendre en charge de manière transparente JSONP
Routage
Express utilise des méthodes HTTP pour fournir une API de routage significative et expressive. Par exemple, nous souhaitons que la recherche de /user/12 affiche le profil de l'utilisateur avec id=12 . Pour ce faire, nous définissons l'itinéraire ci-dessous. Les valeurs associées aux champs nommés sont disponibles dans l'objet res.params.
app.get("/user/:id", function(req, res)( res.send("user " + req.params.id); ));
Une route est simplement une chaîne compilée dans une expression régulière à l’intérieur du moteur. Par exemple, lorsque /user/:id est compilé, le résultat est une expression régulière comme celle-ci :
\/utilisateur\/([^\/]+)\/?
Vous pouvez également transmettre immédiatement une expression régulière. Mais comme les groupes ne sont pas nommés dans les expressions régulières, ils peuvent être atteints dans req.params par des nombres. Ainsi, le premier groupe va dans req.params , le second dans req.params , etc.
app.get(/^\/users?(?:\/(\d+)(?:\.\.(\d+))??/, function(req, res)( res.send(req.params ); ));
Prenons maintenant curl et envoyons une requête à la route ci-dessus :
$ curl http://dev:3000/user $ curl http://dev:3000/users $ curl http://dev:3000/users/1 ["1",null] $ curl http://dev : 3000/utilisateurs/1..15 ["1","15"]
Vous trouverez ci-dessous quelques exemples d'itinéraires et de chemins qui pourraient y correspondre :
"/user/:id" /user/12 "/users/:id?" /users/5 /users "/files/*" /files/jquery.js /files/javascripts/jquery.js "/file/*.*" /files/jquery.js /files/javascripts/jquery.js "/ utilisateur/:id/:opération?" /user/1 /user/1/edit "/products.:format" /products.json /products.xml "/products.:format?" /products.json /products.xml /products "/user/:id.:format?" /utilisateur/12 /utilisateur/12.json
Par exemple, nous pouvons POST du JSON et répondre avec le même JSON en utilisant la couche bodyParser, qui peut analyser une requête JSON (ainsi que d'autres requêtes) et placer la réponse dans req.body :
var express = require("express"), app = express.createServer(); app.use(express.bodyParser()); app.post("/", function(req, res) ( res.send(req.body); )); app.écouter (3000);
En règle générale, nous utilisons un champ « stupide » (par exemple, /user/:id), qui n'a aucune restriction. Mais si nous voulons, par exemple, limiter l’ID utilisateur aux seuls caractères numériques, nous pouvons utiliser /user/:id(+) . Cette construction ne fonctionnera pas si la valeur du champ contient des caractères non numériques.
Transférer le contrôle vers un autre itinéraire
En appelant le troisième argument, next() , vous pouvez passer le contrôle de la route suivante. Si aucune correspondance n'est trouvée, le contrôle est rendu à Connect et les couches continuent d'être appelées dans l'ordre dans lequel elles ont été activées à l'aide de use() . Plusieurs itinéraires partageant le même chemin fonctionnent également. Ils sont simplement appelés un par un jusqu'à ce que l'un d'eux réponde au lieu d'appeler next() .
app.get("/users/:id?", function(req, res, next) ( var id = req.params.id; if (id) ( // faire quelque chose ) else ( next(); ) )) ; app.get("/users", function(req, res) ( // faire autre chose ));
La méthode app.all() est utile si vous souhaitez appliquer la même logique pour toutes les méthodes HTTP. Ci-dessous, nous utilisons cette méthode pour récupérer un utilisateur de la base de données et l'attribuer à req.user.
var express = require("express"), app = express.createServer(); var utilisateurs = [( nom : "tj" )]; app.all("/user/:id/:op?", function(req, res, next) ( req.user = users; if (req.user) ( next(); ) else ( next(new Error( "utilisateur introuvable" + req.params.id)); app.get("/user/:id", function(req, res) ( res.send("viewing " + req.user.name); )); app.get("/user/:id/edit", function(req, res) ( res.send("editing " + req.user.name); )); app.put("/user/:id", function(req, res) ( res.send("updating " + req.user.name); )); app.get("*", function(req, res) ( res.send("quoi???", 404); )); app.écouter (3000);
Intercalaires
Les couches du framework Connect peuvent être transmises à express.createServer() de la même manière que si un serveur Connect standard était utilisé. Par exemple:
var express = require("express"); var app = express.createServer(express.logger(), express.bodyParser());
Vous pouvez également utiliser use() . Cela rend plus pratique l’ajout de couches à l’intérieur des blocs configure(), ce qui est plus progressif.
app.use(express.logger(( format: ":method:url" )));
Généralement, avec les couches Connect, nous pouvons connecter Connect comme ceci :
var connect = require("connecter"); app.use(connect.logger()); app.use(connect.bodyParser());
Ce n'est pas tout à fait pratique, donc Express réexporte les couches Connect :
app.use(express.logger()); app.use(express.bodyParser());
L'ordre des couches est important. Ainsi, lorsque Connect reçoit une requête, la première couche ajoutée via createServer() ou use() est exécutée. Il est appelé avec trois paramètres : requête, réponse et une fonction de rappel, généralement appelée next. lorsque next() est appelé, le contrôle est transféré à la deuxième couche, etc. Il est important d’en tenir compte, car de nombreuses couches dépendent les unes des autres. Par exemple, methodOverride() appelle req.body.method pour surcharger une méthode HTTP, et bodyParser() analyse le corps de la requête pour remplir req.body . Un autre exemple est l'analyse des cookies et la prise en charge de la session - vous devez d'abord appeler use() sur cookieParser() , puis sur session() .
De nombreuses applications Express peuvent avoir la ligne app.use(app.router) . Cela peut paraître étrange, mais il s'agit simplement de spécifier explicitement la couche qui inclut toutes les routes que nous avons créées. Cette couche peut être incluse dans n'importe quel ordre, bien que par défaut elle soit incluse à la fin. En changeant sa position, vous pouvez contrôler l'ordre de son exécution. Par exemple, nous avons besoin d'un gestionnaire d'erreurs qui se déclenchera après toutes les autres couches et affichera toute exception qui lui est transmise à l'aide de next() . Ou il peut être nécessaire de réduire l'ordre d'exécution de la couche servant les fichiers statiques pour permettre à d'autres routes d'intercepter les demandes concernant ces fichiers et, par exemple, de compter le nombre de téléchargements, etc. Voici à quoi cela pourrait ressembler :
app.use(express.logger(...)); app.use(express.bodyParser(...)); app.use(express.cookieParser(...)); app.use(express.session(...)); app.use(app.router); app.use(express.static(...)); app.use(express.errorHandler(...));
Nous ajoutons d’abord logger() – il encapsulera la méthode req.end() pour nous donner des données sur le taux de réponse. Ensuite, nous analysons le corps de la requête (s'il y en a un), puis les cookies, puis la session, de sorte que req.session soit déjà défini lorsque nous arrivons aux routes dans app.router . Si, par exemple, une requête GET vers /javascripts/jquery.js est gérée par des routes et que nous n'appelons pas next() , alors la couche static() ne recevra jamais cette requête. Cependant, si nous définissons un itinéraire comme indiqué ci-dessous, il sera possible d'enregistrer des statistiques, de refuser des téléchargements, de facturer des téléchargements, etc.
var téléchargements = (); app.use(app.router); app.use(express.static(__dirname + "/public")); app.get("/*", function(req, res, next) ( var file = req.params; downloads = downloads || 0; downloads++; next(); ));
Itinéraires en couches
Les routes peuvent utiliser des couches de routage en transmettant des rappels (ou tableaux) supplémentaires à la méthode. Ceci est utile si vous devez restreindre l'accès ou charger des données avant d'utiliser un itinéraire, etc.
En règle générale, la récupération de données asynchrone peut ressembler à celle illustrée ci-dessous (ici, nous prenons le paramètre :id et chargeons les données utilisateur).
app.get("/user/:id", function(req, res, next) ( loadUser(req.params.id, function(err, user) ( if (err) return next(err); res.send( "Affichage de l'utilisateur" + user.name);
Pour adhérer au principe DRY et améliorer la lisibilité du code, vous pouvez organiser cette logique à l'aide de couches. Comme vous pouvez le voir, en faisant abstraction de la logique à l'aide de couches, vous pouvez à la fois réaliser la réutilisation des couches et rendre le code de routage plus beau.
function loadUser(req, res, next) ( // ici nous chargeons l'utilisateur depuis la base de données var user = users; if (user) ( req.user = user; next(); ) else ( next(new Error("Failed pour charger l'utilisateur " + req.params.id)); ) ) app.get("/user/:id", loadUser, function(req, res) ( res.send("Viewing user " + req.user.name ) ; ));
Plusieurs couches de routage peuvent être ajoutées et elles seront exécutées séquentiellement pour fournir une logique différente, telle que restreindre l'accès à un compte utilisateur. Dans l'exemple ci-dessous, seul un utilisateur autorisé peut modifier son compte.
function andRestrictToSelf(req, res, next) ( req.authenticatedUser.id == req.user.id ? next() : next(new Error("Unauthorized")); ) app.get("/user/:id/ edit", loadUser, andRestrictToSelf, function(req, res) ( res.send("Modification de l'utilisateur " + req.user.name); ));
Sachant que les calques ne sont que des fonctions, vous pouvez écrire une fonction qui renvoie un calque (pour fournir une solution encore plus expressive et flexible), comme indiqué ci-dessous.
function andRestrictTo(role) ( return function(req, res, next) ( req.authenticatedUser.role == role ? next() : next(new Error("Unauthorized")); ) ) app.del("/user/ :id", loadUser, andRestrictTo("admin"), function(req, res) ( res.send("Utilisateur supprimé " + req.user.name); ));
Les « piles » de couches fréquemment utilisées peuvent être transmises sous forme de tableaux de profondeur et de structure arborescente arbitraires (elles seront appliquées de manière récursive) :
var a = , b = , tous = ; app.get("/foo", a, function() ()); app.get("/bar", a, function() ()); app.get("/", a, middleware3, middleware4, function() ()); app.get("/", a, b, function() ()); app.get("/", all, function() ());
L'exemple complet peut être trouvé dans le référentiel.
Il arrive parfois que vous deviez ignorer les couches de routes restantes dans la pile, mais continuer à exécuter les routes suivantes. Pour ce faire, appelez next() avec l'argument route : next("route") . S'il ne reste plus de routes à exécuter, Express répondra par une erreur 404 Not Found.
Méthodes HTTP
Nous avons déjà utilisé app.get() à plusieurs reprises, mais Express fournit également d'autres méthodes HTTP - app.post() , app.del() , etc.
Le cas d’utilisation le plus courant du POST est la soumission d’un formulaire. Dans l'exemple ci-dessous, nous créons simplement un formulaire HTML. Et puis le contrôle sera transféré à l’itinéraire que nous définirons dans l’exemple suivant.
Par défaut, Express ne sait pas quoi faire avec le corps de la requête, nous devons donc ajouter une couche bodyParser() qui analysera le corps de la requête encodé dans application/x-www-form-urlencoded ou application/json et mettra le l'analyse des résultats dans req .body . Pour ce faire, nous devons dire use() comme ci-dessous :
app.use(express.bodyParser());
Maintenant, la route ci-dessous accédera à l'objet req.body.user, qui aura des propriétés de nom et d'e-mail :
app.post("/", function(req, res) ( console.log(req.body.user); res.redirect("back"); ));
Si le formulaire utilise des méthodes telles que PUT, vous pouvez utiliser une entrée masquée appelée _method, qui vous permet de modifier la méthode HTTP. Pour y parvenir, il faut d'abord activer une couche methodOverride(), qui sera placée après bodyParser(), ce qui lui permettra d'utiliser le req.body contenant les champs du formulaire soumis.
app.use(express.bodyParser()); app.use(express.methodOverride());
Ces couches ne sont pas activées par défaut, car Express ne dispose pas nécessairement de toutes les fonctionnalités immédiatement. Selon les besoins de l'application, vous n'aurez peut-être pas besoin de les utiliser. Et puis les méthodes PUT et DELETE seront toujours disponibles, mais directement. En même temps, methodOverride est une excellente solution pour les formulaires HTML. Vous trouverez ci-dessous un exemple d'utilisation de la méthode PUT :
app.put("/", function() ( console.log(req.body.user); res.redirect("back"); ));Traitement des erreurs
Express a une méthode app.error() qui accepte toutes les exceptions levées par les routes ou transmises comme next(err) . Vous trouverez ci-dessous un exemple de la manière de servir plusieurs pages à l'aide d'une exception NotFound maison :
function NotFound(msg) ( this.name = "NotFound"; Error.call(this, msg); Error.captureStackTrace(this, arguments.callee); ) NotFound.prototype.__proto__ = Error.prototype; app.get("/404", function(req, res) ( throw new NotFound; )); app.get("/500", function(req, res) ( throw new Error("clavier chat!"); ));
Vous pouvez appeler app.error() plusieurs fois comme indiqué ci-dessous. Ici, nous vérifions l'instance de NotFound et affichons une page 404, ou passons le contrôle au gestionnaire d'erreurs suivant.
Notez que ces gestionnaires peuvent être définis n'importe où, puisqu'ils seront toujours placés sous les gestionnaires de route dans Listen() . Cela permet de les définir dans des blocs configure(), afin que les exceptions puissent être gérées différemment en fonction de l'environnement actuel.
app.error(function(err, req, res, next) ( if (err instanceof NotFound) ( res.render("404.jade"); ) else ( next(err); ) ));
Par souci de simplicité, nous supposons ici que toutes les erreurs ont un code de 500, mais vous pouvez le modifier à votre guise. Par exemple, lorsque Node effectue des opérations sur le système de fichiers, nous pouvons obtenir un objet d'erreur avec un champ error.code = ENOENT, qui signifie « fichier ou répertoire introuvable », nous pouvons l'utiliser dans un gestionnaire d'erreurs et afficher la page correspondante.
app.error(function(err, req, res) ( res.render("500.jade", ( erreur: err )); ));
Les applications peuvent également utiliser la couche errorHander de Connect pour gérer les exceptions. Par exemple, si vous devez afficher les exceptions dans stderr dans l'environnement de développement, vous pouvez procéder comme suit :
app.use(express.errorHandler(( dumpExceptions: true )));
De plus, pendant le développement, nous pouvons avoir besoin de pages HTML sympas qui affichent les exceptions levées ou levées. Dans ce cas, vous devez définir showStack sur true :
app.use(express.errorHandler(( showStack : true, dumpExceptions : true )));
La couche errorHandler répond également en JSON si un en-tête Accept: application/json est passé par le client, ce qui est utile pour développer des applications AJAX.
Paramètres d'itinéraire de prétraitement
Les paramètres d'itinéraire de prétraitement peuvent améliorer considérablement la lisibilité d'une application grâce au chargement explicite des données et à la validation de l'URL de la demande. Par exemple, si vous récupérez constamment des données pour certaines requêtes (par exemple en chargeant des données utilisateur pour /user/:id), vous pouvez faire quelque chose comme ceci :
app.get("/user/:userId", function(req, res, next) ( User.get(req.params.userId, function(err, user) ( if (err) return next(err); res. send("utilisateur " + utilisateur.nom ));
Avec des conditions préalables, nous pouvons attacher des fonctions de rappel à nos paramètres de requête qui effectueraient une validation, restreindraient l'accès ou même chargeraient des données à partir de la base de données. Dans l'exemple ci-dessous, nous appelons app.param() avec le nom du paramètre auquel nous souhaitons attacher un rappel. Comme vous pouvez le voir, nous recevons un argument id, qui contient le nom du champ. De cette façon, nous chargeons l'objet utilisateur et effectuons la gestion habituelle des erreurs et un simple appel à next() pour passer le contrôle à la précondition ou au gestionnaire d'itinéraire suivant.
app.param("userId", function(req, res, next, id) ( User.get(id, function(err, user) ( if (err) return next(err); if (!user) return next( new Error ("échec de la recherche de l'utilisateur")); req.user = user();
Les étapes ci-dessus, comme déjà mentionné, améliorent considérablement la lisibilité du code et permettent d'utiliser facilement la même logique à différents endroits de l'application :
app.get("/user/:userId", function(req, res) ( res.send("user " + req.user.name); ));
Rendu des vues
Afficher les noms de fichiers suivent le schéma (nom). (moteur), où (moteur) est le nom du module de moteur de modèle qui doit être connecté. Par exemple, la vue layout.ejs indique au système de vue de faire require("ejs") . Pour s'intégrer à Express, le module chargeable doit exporter une méthode, exports.compile(str, options) et renvoyer une fonction. Pour modifier ce comportement, vous pouvez utiliser la méthode app.register() - elle vous permet d'associer des extensions de fichiers à des moteurs spécifiques. Par exemple, vous pouvez rendre foo.html par le moteur ejs.
Ci-dessous un exemple utilisant Jade pour rendre index.html . Et comme nous n'utilisons pas layout:false , le contenu rendu de la vue index.jade sera transmis en tant que variable de corps locale à la vue layout.jade.
app.get("/", function(req, res) ( res.render("index.jade", ( titre : "Mon site" )); ));
La configuration du moteur d'affichage vous permet de spécifier le moteur de modèle par défaut. Ainsi, par exemple, lorsque vous utilisez Jade, vous pouvez faire ceci :
app.set("moteur d'affichage", "jade");
ce qui nous permettra de rendre ainsi :
res.render("index");
Mais pas comme ça :
res.render("index.jade");
Lorsque le moteur de modèles est installé via le moteur d'affichage, les extensions de fichiers ne sont pas nécessaires. Cependant, nous pouvons toujours utiliser plusieurs moteurs de modèles à la fois :
res.render("une autre-page.ejs");
Express dispose également d'un paramètre d'options d'affichage qui sera appliqué à chaque rendu de la vue. Par exemple, si vous n’utilisez pas souvent des mises en page, vous pouvez l’écrire comme ceci :
app.set("options d'affichage", ( mise en page : false ));
Qui peut ensuite être surchargé si nécessaire dans un appel à res.render() :
res.render("myview.ejs", ( mise en page : true ));
Lorsque vous avez besoin d'une mise en page différente, vous pouvez également spécifier le chemin. Par exemple, si le moteur d'affichage est défini sur jade et que le fichier de mise en page s'appelle ./views/mylayout.jade , nous pouvons simplement transmettre :
res.render("page", ( mise en page : "mylayout" ));
Sinon, vous pouvez passer l'extension du fichier :
res.render("page", ( mise en page : "mylayout.jade" ));
Les chemins peuvent également être absolus :
res.render("page", ( mise en page : __dirname + "/../../mylayout.jade" ));
Un bon exemple est la spécification de balises de moteur d'ouverture et de fermeture non standard. ejs:
app.set("options d'affichage", ( open: "((", close: "))" ));
Afficher des fragments
Le système de vue Express prend en charge les fragments et les collections, une sorte de mini-vue. Par exemple, au lieu de parcourir la vue pour afficher une liste de commentaires, vous pouvez simplement utiliser un fragment de collection :
partial("commentaire", (collection : commentaires));
Si d'autres options ou variables locales ne sont pas nécessaires, vous pouvez ignorer l'objet et simplement transmettre le tableau de données. L'exemple ci-dessous est équivalent au précédent :
partial("commentaire", commentaires);
Lorsque nous utilisons des collections, nous disposons de plusieurs variables locales « magiques » :
- firstInCollection - vrai s'il s'agit du premier objet
- indexInCollection - index de l'objet dans la collection
- lastInCollection - vrai s'il s'agit du dernier objet
- collectionLength - longueur de la collection
Les variables locales transmises ou générées sont prioritaires, mais les variables locales transmises à la vue parent sont également disponibles pour la vue enfant. Ainsi, par exemple, si nous rendons une vue en utilisant partial("blog/post", post) et qu'elle produit une variable locale post et que la vue qui a appelé cette fonction avait une variable locale user , alors l'utilisateur sera également visible dans le blog. /post-vue.
Voir res.partial() pour plus de documentation.
Remarque : utilisez les collections avec précaution, car le rendu d'un tableau de 100 éléments signifie le rendu de 100 vues. Pour les collections simples, il est préférable de parcourir la vue plutôt que d’utiliser des collections. De cette façon, la charge sera moindre.
Rechercher des vues
Les vues sont recherchées par rapport à la vue parent. Par exemple, si nous avons une vue vues/user/list.jade et que nous appelons à l'intérieur partial("edit") , le système essaiera de charger la vue vues/user/edit.jade , alors que partial("../ messages") entraînera le téléchargement de vues/messages.jade
Le système de visualisation vous permet également de créer des fichiers d'index. Par exemple, nous pouvons appeler res.render("users") et cela peut charger à la fois Views/users.jade et Views/users/index.jade .
Vous pouvez également utiliser des fichiers d'index à partir d'une vue dans le même répertoire. Ainsi, appeler partial("users") peut accéder à la vue ../users/index au lieu d'appeler partial("index") .
Moteurs de modèles
Vous trouverez ci-dessous quelques moteurs de modèles couramment utilisés avec Express :
- E.J.S.- JavaScript intégré
- CaféKup- basé sur un modèle CaféScript
- Modèles jQuery pour le nœud
Prise en charge des sessions
La prise en charge des sessions peut être activée à l'aide de la couche de session de Connect. Pour cela également, nous avons besoin d'une couche cookieParser sus-jacente, qui analysera les cookies et les placera dans req.cookies.
app.use(express.cookieParser()); app.use(express.session(( secret: "clavier chat" )));
Par défaut, la couche session utilise le stockage en mémoire de Connect, mais il existe de nombreuses autres solutions. Par exemple connecter-redis prend en charge le stockage de session dans Rédis. Voici comment l'utiliser :
var RedisStore = require("connect-redis")(express); app.use(express.cookieParser()); app.use(express.session(( secret : "clavier chat", magasin : nouveau RedisStore )));
Désormais, les propriétés req.session et req.sessionStore seront disponibles à partir de toutes les routes et couches suivantes. Les propriétés req.session sont automatiquement enregistrées lors de la réponse. Voici comment organiser votre panier :
var RedisStore = require("connect-redis")(express); app.use(express.bodyParser()); app.use(express.cookieParser()); app.use(express.session(( secret : "clavier chat", magasin : nouveau RedisStore ))); app.post("/add-to-cart", function(req, res) ( // disons que nous avons passé plusieurs objets du formulaire // utilisons bodyParser() pour cela var items = req.body.items; req. éléments de session = éléments; res.redirect("retour" )); app.get("/add-to-cart", function(req, res) ( // Lorsque nous redirigeons vers GET /add-to-cart // nous pouvons vérifier req.session.items && req.session.items . length // pour imprimer notre message if (req.session.items && req.session.items.length) ( req.flash("info", "Vous avez %s articles dans votre panier", req.session.items. length ); res.render("panier");
L'objet req.session possède également les méthodes Session.touch() , Session.destroy() , Session.regenerate() pour manipuler les sessions. Pour des informations plus complètes, consultez la documentation de la session Connect.
Guide de migration
Les développeurs qui ont travaillé avec Express 1.x peuvent se référer au guide de migration pour faire fonctionner leurs applications avec Express 2.x, Connect 1.x et Node 0.4.x.
Demande
req.header(clé[, valeur par défaut])
Obtenez l'en-tête de demande de clé (insensible à la casse) avec une valeur par défaut facultative :
req.header("Hôte"); req.header("hôte"); req.header("Accepter", "*/*");
Les en-têtes Referrer et Referer constituent un cas particulier. Les deux constructions fonctionneront :
// a envoyé l'en-tête "Referrer : http://google.com" req.header("Referer"); // => "http://google.com" req.header("Référent"); // => "http://google.com"
req.accepte (type)
Vérifie si l'en-tête Accept est transmis et s'il correspond au type donné.
Lorsque l’en-tête Accept est manquant, true est renvoyé. Sinon, le type correspond, puis les sous-types sont vérifiés. Il est possible de transmettre "html" qui est converti en interne en "text/html" à l'aide d'une table de recherche MIME.
// Accepter : text/html req.accepts("html"); // => vrai // Accepte : text/*; application/json req.accepts("html"); req.accepte("texte/html"); req.accepte("text/plain"); req.accepte("application/json"); // => true req.accepts("image/png"); req.accepte("png"); // => faux
req.is(type)
Vérifie la demande entrante pour voir si elle a un en-tête Content-Type et correspond au type MIME spécifié.
// Laissez Content-Type: text/html; charset=utf-8 req.is("html"); req.is("texte/html"); // => true // Laissez le Content-Type être maintenant application/json req.is("json"); req.is("application/json"); // => true req.is("html"); // => faux
Dans Express, vous pouvez enregistrer vos propres rappels pour diverses vérifications de demandes. Par exemple, disons que nous devons effectuer une vérification minutieuse pour voir si la requête entrante est une image. Pour ce faire, vous pouvez enregistrer le rappel « une image » :
app.is("une image", function(req) ( return 0 == req.headers["content-type"].indexOf("image"); ));
Vous pouvez maintenant l'utiliser dans les gestionnaires de routes pour vérifier le type de contenu du formulaire "image/jpeg", "image/png", etc.
app.post("/image/upload", function(req, res, next) ( if (req.is("une image")) ( // effectuer certaines actions ) else ( next(); ) ));
N'oubliez pas que cette méthode ne s'applique pas uniquement au Content-Type - vous pouvez effectuer tout type de vérification.
Vous pouvez également utiliser des caractères génériques. Cela simplifiera notre exemple d’image. Ici, nous vérifierons uniquement le type :
req.is("image/*");
Nous pouvons également vérifier le sous-type comme indiqué ci-dessous. Ici, la vérification retournera true dans les cas de "application/json" et "text/json" .
req.is("*/json");
req.param(nom[, valeur par défaut])
Renvoie la valeur du nom du paramètre ou - s'il n'existe pas - default .
Vérifie les paramètres de route (req.params), par exemple /user/:id
Vérifie les paramètres de la chaîne de requête (req.query), par exemple ?id=12
Vérifie les paramètres codés en URL du corps de la requête (req.body), par exemple, id=12
Pour recevoir les paramètres du corps de la requête codés en urlen, un objet req.body doit exister. Pour ce faire, activez la couche bodyParser().
req.get (champ, paramètre)
Obtient le paramètre du champ d'en-tête. La valeur par défaut est une chaîne vide.
req.get("content-disposition", "nom de fichier"); // => "quelque chose.png" req.get("Content-Type", "boundary"); // => "--foo-bar-baz"
req.flash(type[, msg])
Met en file d'attente le message contextuel.
req.flash("info", "email envoyé"); req.flash("erreur", "échec de la livraison du courrier électronique"); req.flash("info", "email renvoyé"); // => 2 req.flash("info"); // => ["email envoyé", "email renvoyé"] req.flash("info"); // => req.flash(); // => ( erreur : ["échec de la livraison par e-mail"], info : )
Les messages contextuels peuvent également utiliser des chaînes de format. La chaîne par défaut "%s" est disponible :
req.flash("info", "échec de la remise du courrier électronique à _%s_ depuis _%s_.", toUser, fromUser);
req.isXMLHttpRequest
Également abrégé req.xhr. Vérifie l'en-tête X-Requested-With pour voir si la requête a été effectuée à l'aide d'un XMLHttpRequest :
req.xhr req.isXMLHttpRequest
Réponse
res.header(clé[, val])
Obtient ou définit l'en-tête de réponse.
res.header("Content-Length"); // => non défini res.header("Content-Length", 123); // => 123 res.header("Content-Length"); // => 123
res.charset
Définit le codage des en-têtes Content-Type suivants. Par exemple, res.send() et res.render() seront par défaut "utf8" et nous pouvons définir explicitement l'encodage avant de restituer le modèle :
res.charset = "ISO-8859-1" ; res.render("utilisateurs");
ou avant de répondre avec res.send() :
res.charset = "ISO-8859-1" ; res.send(str);
ou en utilisant res.end() intégré à Node :
res.charset = "ISO-8859-1" ; res.header("Content-Type", "text/plain"); res.end(str);
res.contentType(type)
Définit l’en-tête de réponse Content-Type.
var filename = "chemin/vers/image.png"; res.contentType(nom de fichier); // Content-Type est maintenant "image/png"
Vous pouvez également définir Content-Type avec la chaîne suivante :
res.contentType("application/json");
Ou simplement l'extension du fichier (sans le point initial) :
res.contentType("json");
res.attachment()
Définit l’en-tête de réponse Content-Disposition sur "attachment" . Facultativement, un nom de fichier peut être transmis.
res.attachment("chemin/vers/mon/image.png");
res.sendfile(chemin[, options[, rappel]])
Utilisé dans res.download() pour transférer un fichier arbitraire.
res.sendfile("chemin/vers/mon.fichier");
Cette méthode accepte un paramètre de rappel facultatif, qui est appelé si le transfert de fichier échoue ou réussit. Par défaut, next(err) est appelé, mais si un rappel est passé, cela doit être fait explicitement ou gérer l'erreur.
res.sendfile(path, function(err) ( if (err) ( next(err); ) else ( console.log("transferred %s", path); ) ));
Vous pouvez également transmettre des options à l'appel fs.createReadStream(). Par exemple, pour modifier la taille du tampon :
res.sendfile(path, ( bufferSize: 1024 ), function(err) ( // traitement... ));
res.download(file[, filename[, callback[, callback2]]])
Téléchargez ce fichier en pièce jointe (vous pouvez spécifier un autre nom de fichier facultatif).
res.download('chemin/vers/image.png');
res.download('chemin/vers/image.png', 'foo.png');
Cela équivaut à ce qui suit :
res.attachment(fichier); res.sendfile(fichier);
Facultativement, vous pouvez spécifier un rappel comme deuxième ou troisième argument de res.sendfile() . Dans celui-ci, vous pouvez répondre comme si l'en-tête n'avait pas encore été transmis.
res.download(path, "expenses.doc", function(err) ( // traitement... ));
Vous pouvez également éventuellement transmettre un deuxième rappel - callback2 . Il gère les erreurs liées à la connexion. Toutefois, il ne doit pas tenter d’envoyer une réponse.
res.download(path, function(err) ( // erreur ou terminaison), function(err) ( // erreur de connexion ));
res.send(corps|statut[, en-têtes|statut[, statut]])
La méthode res.send() est une fonction de réponse de haut niveau qui vous permet de transmettre des objets (pour une réponse JSON), des chaînes (pour une réponse HTML), des instances de tampon ou des entiers spécifiant un code d'état (404, 500, etc. .) . Voici comment il est utilisé :
res.send(); // 204 res.send(new Buffer("wahoo")); res.send((certains : "json" )); res.send(""); res.send("Désolé, je ne trouve pas ça", 404); res.send("texte", ( "Content-Type": "text/plain" ), 201); res.send(404);
Par défaut, l'en-tête Content-Type est défini automatiquement. Cependant, s'il a été défini manuellement explicitement dans res.send() ou avant d'utiliser res.header() , ou d'utiliser res.contentType() , il ne sera pas automatiquement défini.
Notez que cette méthode termine la réponse (similaire à res.end()), donc si vous devez produire plusieurs réponses ou un flux, vous devez utiliser res.write() .
res.json(obj[, en-têtes|statut[, statut]])
Envoie une réponse JSON avec des en-têtes et un code d'état facultatifs. Cette méthode est idéale pour organiser une API JSON, mais JSON peut également être envoyé en utilisant res.send(obj) (ce qui n'est pas idéal si vous souhaitez uniquement envoyer une chaîne codée en JSON, puisque res.send(string) enverra du HTML)
res.json(null); res.json((utilisateur : "tj" )); res.json("garde!", 500); res.json("Rien trouvé", 404);
res.redirect(url[, statut])
Redirige vers l'URL spécifiée. Le code d'état par défaut est 302.
res.redirect("/", 301); res.redirect("/compte"); res.redirect("http://google.com"); res.redirect("accueil"); res.redirect("retour");
Express prend en charge les raccourcis pour les redirections – ceux par défaut sont "back" et "home" . Dans ce cas, "back" redirige vers l'URL spécifiée dans l'en-tête Referrer (ou Referer), et "home" utilise le paramètre "home" (par défaut "/").
res.cookie(nom, val[, options])
Définit la valeur du cookie nommé name sur val . Options : httpOnly, sécurisé, expire, etc. L'option path prend par défaut la valeur définie dans le paramètre "home", généralement "/" .
// "Se souvenir de moi" pendant 15 minutes res.cookie("rememberme", "yes", ( expires: new Date(Date.now() + 900000), httpOnly: true ));
La propriété maxAge peut être définie pour expirer par rapport à Date.now() en millisecondes. Notre exemple ci-dessus peut donc maintenant être réécrit comme suit :
res.cookie("souviens-toi de moi", "oui", ( maxAge: 900000 ));
Pour analyser les cookies entrants, utilisez la couche cookieParser, qui crée un objet req.cookies :
app.use(express.cookieParser()); app.get("/", function(req, res) ( // utilise req.cookies.rememberme ));
res.clearCookie(nom[, options])
Nous effaçons le cookie nommé name , en attribuant au paramètre expires une date dans un passé lointain. Les options sont les mêmes que pour res.cookie() , le chemin est également par défaut le paramètre "home".
res.clearCookie("souviens-toi de moi");
res.render(view[, options[, fn]])
Rend une vue avec les options données et un rappel fn facultatif. Lorsque fn est donné, la réponse au client n'est pas automatique, sinon une réponse texte/html est effectuée avec le code 200 .
Les options passées sont également des variables de vue locale. Par exemple, si nous voulons transmettre la variable utilisateur et désactiver la mise en page, nous le faisons dans un seul objet :
var utilisateur = ( nom : "tj" ); res.render("index", ( mise en page : false, utilisateur : utilisateur ));
L'objet options est également utilisé pour transmettre des options. Par exemple, si vous transmettez la propriété status, non seulement elle devient disponible pour la vue, mais elle définit également le code d'état de la réponse. Ceci est également utile si le moteur de modèle accepte certaines options, telles que debug ou compress . Vous trouverez ci-dessous un exemple de la façon dont vous pouvez afficher une page d'erreur - le statut est transmis ici à la fois pour l'afficher et pour définir le code d'état res.statusCode .
res.render("erreur", ( statut : 500, message : "Erreur interne du serveur" ));
res.partial(vue[, options])
Rend un fragment avec les options données. Cette méthode est toujours accessible depuis la vue en tant que variable locale.
- object - l'objet passé à la vue
- tout comme le nom de la variable qui représentera l'objet objet ou chaque élément de la collection passé à la vue. La valeur par défaut est le nom de la vue.
- comme : "quelque chose" - ajoutera une variable locale quelque chose
- as: this - utilisera l'élément de collection comme contexte de vue (this)
- as: global - fusionnera les propriétés de l'élément de collection et les variables de vue locale
- collection - un ensemble d'objets. Son nom vient du nom de la vue. Par exemple, video.html contiendra un objet vidéo à l'intérieur.
Les constructions suivantes sont équivalentes les unes aux autres et le nom de collection transmis au fragment sera toujours "movie" .
partial("theatre/movie.jade", (collection : films )); partial("theatre/movie.jade", films); partial("movie.jade", (collection : films )); partial("film.jade", films); partial("film", films); // Dans la vue : moovie.director
Pour changer le nom d'une variable locale de "film" à "vidéo", vous pouvez utiliser l'option as :
partial("film", (collection : films, comme : "vidéo" )); // Dans la vue : video.director
Nous pouvons également définir movie la valeur this dans notre vue afin qu'au lieu de movie.director nous puissions faire référence à this.director .
partial("film", (collection : films, comme : this )); // À l'intérieur de la vue : this.director
Une solution alternative consiste à étendre les propriétés d'un élément de collection en variables pseudo-globales (en fait locales) en utilisant as : global , qui est du sucre syntaxique :
partial("film", (collection : films, as : global )); // À l'intérieur de la vue : réalisateur
La même logique s'applique non seulement aux collections, mais également à un objet dans une vue fragmentée :
partial("film", ( objet : film, comme : ceci )); // À l'intérieur de la vue : this.director partial("movie", ( object: movie, as: global )); // À l'intérieur de la vue : réalisateur partial("movie", ( object: movie, as: "video" )); // À l'intérieur de la vue : video.director partial("movie", ( object: movie )); // réalisateur de cinéma
Lorsque le deuxième argument n'est pas une collection (sans .length), il est traité comme un objet. Dans ce cas, le nom de la variable locale de cet objet est formé à partir du nom de la vue.
var movie = new Movie("L'Étrange Noël de Monsieur Jack", "Tim Burton") partial("movie", movie) // => Dans la vue : movie.director
L'exception à cette règle est lorsqu'un objet simple ("()" ou "nouvel objet") est transmis, il est alors considéré comme un objet local et n'est pas accessible par son nom dans une vue fragmentée. Par exemple, dans l'exemple suivant, vous vous attendez à ce qu'il y ait une variable locale "movie" , mais comme il s'agit d'un objet simple, les variables locales sont déjà "director" et "title" , c'est-à-dire ses propriétés :
var movie = ( titre : "L'Etrange Noël de Monsieur Jack", réalisateur : "Tim Burton" ); partiel("film", film)
Dans de tels cas, lorsque vous devez transmettre un objet simple, attribuez-le simplement à une propriété ou utilisez la propriété d'objet, qui héritera du nom de l'objet du nom de fichier. Les exemples listés ci-dessous sont équivalents :
partial("film", ( locaux : ( film: film )) partial("film", ( film: film )) partial("film", ( objet: film ))
La même API peut être utilisée à partir d'une route afin que vous puissiez répondre avec un fragment HTML via AJAX ou WebSockets, par exemple vous pouvez restituer une collection d'utilisateurs directement à partir de la route :
app.get("/users", function(req, res) ( if (req.xhr) ( // envoie en réponse chaque utilisateur de la collection // passé à la vue "user" res.partial("user", users) ; ) else ( // répond avec une mise en page complète avec une page de liste d'utilisateurs // dont le modèle fait partial("user", users) // et ajoute une sorte d'interface res.render("users", ( utilisateurs : utilisateurs ) ) ) ) ;
res.local(nom[, val])
Obtenez ou définissez la variable locale spécifiée. Dans ce cas, les variables locales font référence aux variables transmises aux méthodes de rendu de la vue, telles que res.render() .
app.all("/movie/:id", function(req, res, next) ( Movie.get(req.params.id, function(err, movie) ( // Effectue l'affectation res.locals.movie = movie res .local("film", film )); app.get("/movie/:id", function(req, res) ( // la variable locale movie existe déjà // mais on peut l'ajouter si besoin res.render("movie", ( displayReviews: true ) ); ));
res.locals(obj)
Attribuez plusieurs variables locales à l’aide de l’objet obj donné. Ce qui suit est équivalent :
res.local("foo", bar); res.local("bar", baz); res.locals(( foo: bar, bar, baz ));
Serveur
app.set(nom[, val])
Définissez le paramètre de nom de l'application sur val , ou obtenez la valeur du paramètre de nom si val est manquant :
app.set("views", __dirname + "/views"); app.set("vues"); // => ...chemin...
Vous pouvez également accéder aux paramètres via appsettings :
app.settings.views // => ...chemin...
app.enable(nom)
Définit le paramètre de nom sur true :
app.enable("un paramètre arbitraire"); app.set("un paramètre arbitraire"); // => true app.enabled("un paramètre arbitraire"); // => vrai
app.enabled(nom)
Vérifie si le paramètre de nom est vrai :
app.enabled("afficher le cache"); // => false app.enable("afficher le cache"); app.enabled("afficher le cache"); // => vrai
app.disable(nom)
Définissez le paramètre de nom sur false :
app.disable("certains paramètres"); app.set("certains paramètres"); // => false app.disabled("certains paramètres"); // => faux
app.disabled(nom)
Vérifie si le paramètre de nom est faux :
app.enable("afficher le cache"); app.disabled("afficher le cache"); // => false app.disable("afficher le cache"); app.disabled("afficher le cache"); // => vrai
app.configure(env|fonction[, fonction])
Spécifie la fonction de rappel pour l'environnement env (ou pour tous les environnements) :
app.configure(function() ( // s'exécute pour tous les environnements )); app.configure("development", function() ( // exécuté uniquement pour l'environnement "development"));
app.redirect(nom, val)
Pour res.redirect(), nous pouvons définir des raccourcis (dans le champ d'application) comme ci-dessous :
app.redirect("google", "http://google.com");
Maintenant, dans l'itinéraire, nous pouvons appeler :
res.redirect("google");
Vous pouvez également faire des abréviations dynamiques :
app.redirect("comments", function(req, res) ( return "/post/" + req.params.id + "/comments"; ));
Vous pouvez maintenant effectuer les opérations suivantes et la redirection sera construite dynamiquement en fonction du contexte de la demande. Si nous avons appelé la route avec GET /post/12, notre redirection sera /post/12/comments.
app.get("/post/:id", function(req, res) ( res.redirect("comments"); ));
Dans le cas d'une application montée, res.redirect() prendra en compte le point de montage de l'application. Par exemple, si l'application de blog est montée sur /blog , l'exemple suivant redirigera vers /blog/posts :
res.redirect("/posts");
app.erreur (fonction)
Ajoute une fonction de gestionnaire d'erreurs dont le premier paramètre acceptera toutes les exceptions, comme indiqué ci-dessous. Notez qu'il est possible de définir plusieurs gestionnaires d'erreurs en appelant cette méthode plusieurs fois, cependant la méthode doit appeler next() si elle ne veut pas gérer l'exception elle-même :
app.error(function(err, req, res, next) ( res.send(err.message, 500); ));
app.helpers(obj)
Enregistre les assistants de vue statique.
app.helpers(( nom : fonction (premier, dernier) ( return first + ", " + last ), firstName : "tj", lastName : "holowaychuk" ));
Notre vue peut désormais utiliser les variables firstName et lastName et la fonction name().
<%= name(firstName, lastName) %>
Express fournit également plusieurs variables locales par défaut :
- paramètres - objet de paramètres d'application
- layout(path) spécifie la mise en page directement depuis l'intérieur de la vue
Cette méthode est alias app.locals() .
app.dynamicHelpers(obj) (#app.dynamic-helpers)
Enregistre les assistants de vue dynamique. Les assistants de vue dynamiques sont simplement des fonctions qui prennent res , req et sont exécutées dans le contexte de l'instance du serveur avant de restituer une vue. La valeur de retour d'une telle fonction devient une variable locale à laquelle la fonction est associée.
app.dynamicHelpers(( session: function(req, res) ( return req.session; ) ));
Désormais, toutes nos vues auront accès à la session - les données de session seront disponibles à la manière de session.name, etc. :
<%= session.name %>
app.lookup
Renvoie les gestionnaires de route associés au chemin donné.
Disons qu'il existe ces itinéraires :
Vous pouvez utiliser la fonctionnalité de recherche pour vérifier quels itinéraires sont spécifiés. Cela peut être utile pour les frameworks de niveau supérieur construits sur Express.
app.lookup.get("/user/:id"); // => app.lookup.get("/user/:id/:op?"); // => app.lookup.put("/user/:id"); // => app.lookup.all("/user/:id"); // => app.lookup.all("/hé"); // =>
L'alias de app.lookup.HTTP_METHOD() est simplement app.HTTP_METHOD() - sans l'argument de rappel. C'est la réduction. Par exemple, ce qui suit est équivalent :
app.lookup.get("/user"); app.get("/user");
Chaque fonction renvoyée est complétée par des propriétés utiles :
var fn = app.get("/user/:id/:op?"); fn.regexp // => /^\/user\/(?:([^\/]+?))(?:\/([^\/]+?))?\/?$/i fn .keys // => ["id", "op"] fn.path // => "/user/:id/:op?" fn.method // => "OBTENIR"
app.match
Renvoie un tableau de fonctions de rappel qui se déclenchent sur l'URL donnée, qui peuvent contenir une chaîne de requête, etc. Cela peut être utile pour comprendre quelles routes ont la capacité de répondre.
Disons que nous avons les itinéraires suivants :
app.get("/user/:id", function() ()); app.put("/user/:id", function() ()); app.get("/user/:id/:op?", function() ());
L'appel de match sur GET renverra deux fonctions car le :op dans la dernière route est un paramètre facultatif.
app.match.get("/user/1"); // =>
Et le prochain appel ne renverra qu'un seul rappel pour /user/:id/:op? .
app.match.get("/user/23/edit"); // =>
Nous pouvons également utiliser all() si la méthode HTTP n'est pas importante pour nous
app.match.all("/user/20"); // =>
Chaque fonction est dotée des propriétés suivantes :
var fn = app.match.get("/user/23/edit"); fn.keys // => ["id", "op"] fn.params // => ( id : "23", op : "edit" ) fn.method // => "GET"
app.monté (fn)
Attribuez un rappel à fn qui est appelé lorsque ce serveur est transmis à Server.use() .
var app = express.createServer(), blog = express.createServer(); blog.mount(function(parent) ( //le parent est une application // ceci est un blog )); app.use(blog);
app.register (ext, exportations)
Associe les propriétés d'exportation spécifiées (exportations) du moteur de modèle à l'extension ext du fichier modèle.
app.register(".html", require("jade"));
Cela peut également être utile dans le cas de bibliothèques dont le nom ne correspond pas exactement à l'extension du fichier modèle. Exemple vivant - Haml.js, qui est installé npm-om en tant que "hamljs" et nous pouvons l'enregistrer avec des modèles ".haml" plutôt qu'avec ".hamljs" comme ce serait la valeur par défaut :
app.register(".haml", require("haml-js"));
De plus, app.register est très utile dans le cas de moteurs de modèles dont l'API n'est pas conforme aux spécifications Express. Dans l'exemple ci-dessous nous associons l'extension .md au moteur de rendu réduction-des dossiers. Nous effectuerons le rendu en HTML uniquement la première fois - pour de meilleures performances - et nous prendrons en charge la substitution de variable de la forme "(nom)".
app.register(".md", ( compile: function(str, options) ( var html = md.toHTML(str); return function(locals) ( return html.replace(/\(([^)]+) \)/g, function(_, name) ( return locals; ) ));
app.écouter()
Nous lions le socket du serveur d'application à l'adresse host:port. Le port par défaut est 3000, l'hôte est INADDR_ANY.
app.écouter(); app.écouter (3000); app.listen(3000, "n.n.n.n");
L'argument port peut également être une chaîne représentant le chemin d'accès à socket de domaine Unix:
app.listen("/tmp/express.sock");
Essayons maintenant :
$ telnet /tmp/express.sock GET / HTTP/1.1 HTTP/1.1 200 OK Type de contenu : text/plain Longueur du contenu : 11 Hello World
Acteurs du projet
Les principaux contributeurs au projet étaient les suivants :
- TJ Holowaychuk (visionmedia)
- Ciaran Jessup (ciaranj)
- Aaron Heckmann (aheckmann)
- Guillermo Rauch (guille)
Modules tiers
Les modules suivants fonctionnent avec ou sont construits sur Express :
- fournit le routage des ressources
- messages express rendant les notifications contextuelles
- prise en charge express-configure pour la configuration asynchrone (chargement de données depuis Redis, etc.)
- express-namespace - espaces de noms dans les routes
- express-expose publie simplement le code JS côté client de l'application
- express-params - extensions app.param()
- express-mongoose - plugin pour restituer facilement les résultats des requêtes Mongoose (ORM pour MongoDB)
Node JS et bases d'Express (III).
Comprenons ce qu'est npm et à quoi il sert. Installez le moteur de modèles Express et EJS. Nous effectuons tout le travail préparatoire et commençons à créer notre propre site Web dans NodeJS.Maintenant avec des paramètres qui changeront constamment.
Si nous devons créer une référence à une certaine valeur, après /mews/value . Ça va changer. Par exemple : 23, partie ou toute autre valeur.App.get("/news/:id", function(req, res)( res.send("ID est - " + req.params.id); ));
En fonction de ce paramètre, on peut récupérer des données de la base de données (base de données) et afficher un article spécifique.
Nous avons besoin d'un certain fichier html dans lequel nous transférerons les données de notre identifiant et, en fonction de ces données, afficherons telle ou telle information.
Nous en avons besoin moteur de modèle.
Grâce à Express, nous pouvons utiliser plusieurs moteurs de modèles.
Étant donné qu'EJS est un package facultatif, nous devons l'installer.
appuyez sur Entrée
Après cela, il sera installé dans notre projet.
Il vous permet de transmettre des données à différents modèles, et ces modèles auront une extension .ejs.
Dans ces modèles, nous pourrons afficher notre code html ainsi que le code js qui y est inséré (variables, boucles de sortie et bien plus encore).
Il y aura un modèle de page qui changera en fonction des données qui y sont transférées.
La première chose que nous devons faire est de spécifier le moteur de visualisation que nous utiliserons.
Le moteur de visualisation est essentiellement un moteur de modèles.
Comme il y en a un très grand nombre et que nous avons choisi EJS, nous devons l'indiquer dans notre fichier index.js.
Immédiatement après l'initialisation de la variable d'application.
App.set("view-engine", "ejs");
Tous les fichiers que nous afficherons seront recherchés par défaut dans le dossier vues.
Au même niveau où index.js nous allons créer un dossier de vues.
Dans celui-ci, nous créerons un nouveau fichier news.ejs. Ce sera une sorte de modèle que nous remplirons.
Nous pouvons insérer le code HTML le plus courant dans ces modèles.
Page d'actualités.
Pour ce faire, je n'ai pas besoin d'utiliser la méthode .send ou .sendFile, mais j'aurai besoin de la méthode render().
La méthode render() prend le fichier souhaité (modèle) dans le dossier vues et peut l'afficher dans le navigateur. De plus, il peut transmettre certains paramètres à ce modèle.
L'extension ne peut pas être spécifiée dans la méthode render(). Ensuite, vous pouvez transmettre certains paramètres au modèle lui-même. Par conséquent, nous passons l’objet comme deuxième paramètre. Il peut contenir un grand nombre de propriétés et de valeurs.
Disons que nous avons décidé de transmettre un certain paramètre newsId avec la valeur req.params.id - c'est-à-dire que la valeur sera l'identifiant appelé lui-même.
App.get("/news/:id", function(req, res)( render("news", (newsId: req.params.id)); ));
Ainsi, une valeur sera passée au modèle de news, qui sera appelée newsId avec la valeur id .
Nous pouvons accepter et afficher tout cela dans le fichier news.ejs.
Modifions un peu notre fichier news.ejs. Nous afficherons l’ID dans le titre de la page.
Tout se trouve dans la documentation du moteur de template EJS (lien ci-dessus).
Page d'actualités avec ID =<%= newsId %>
Fichier /views/news.ejs
Page d'actualités avec ID =<%= newsId %>
Lorem ipsum dolor sit amet, consectetur adipisicing elit. Eaque numquam libero, veniam ipsum similique odit molestiae esse quia blanditiis magni debitis aliquam, pariatur nam quaerat quas nemo, facilis temporibus laboriosam sit amet, consectetur adipisicing elit. Maiores enim vitae dolore nemo quas aliquam quia corrupti rerum ipsam ad nesciunt, architecto, pariatur officiis. Maxime iste ullam quibusdam, nobis voluptas !
fichier index.js
Soit express = require("express"); laissez app = express(); app.set("afficher le moteur", "ejs"); app.get("/", function(req, res)( res.sendFile(__dirname + "/index.html"); )); app.get("/about", function(req, res)( res.sendFile(__dirname + "/about.html"); )); app.get("/news/:id", function(req, res)( res.render("news", (newsId: req.params.id)); )); app.listen(8080);
Nous pouvons transmettre plusieurs paramètres. Par exemple:
App.get("/news/:id", function(req, res)( res.render("news", (newsId : req.params.id, newParam : 535 )); ));
Et dans le fichier news.ejs nous l'afficherons sur la page, par exemple comme ceci :
<%= newParam %>
De plus, nous pouvons transférer nos propres objets. Par exemple, créons un objet :
App.get("/news/:id", function(req, res)( let obj = (titre : "Actualités", id : 4); res.render("news", (newsId : req.params.id, newParam : 535)); ));
Et on peut aussi transférer cet objet. Tout d’abord, nous déterminons le nom de ce que nous allons transmettre, puis nous indiquons ce que nous transmettons.
Par exemple:
App.get("/news/:id", function(req, res)( let obj = ( title:"News", id: 4); res.render("news", (newsId: req.params.id , newParam : 535, obj : obj ));
Titre =<%= obj.title %>
ID=<%= obj.id %>
<%= newParam %>
Passer un tableau au modèle.
Créons un tableau de données et affichons-le à l'aide d'une boucle.App.get("/news/:id", function(req, res)( let obj = ( title:"News", id: 4, paragraphes :["Paragraphe", "Texte brut", "Nombres : 3, 7, 24", 476]); res.render("news", (newsId : req.params.id, newParam : 535, obj : obj)); ));
Maintenant, dans le modèle lui-même, nous allons simplement afficher ce tableau dans une boucle :
-
<% obj.paragraphs.forEach(function(item) { %>
- <%= item %> <% }); %>
Fichiers statiques et middleware.
Fichiers pouvant être inclus dans d'autres fichiers.
Nous avons maintenant un modèle - news.ejs, mais imaginez. qu'ils sont nombreux. Douzaines. Et vous devrez apporter des modifications à une partie du code qui apparaît dans tous ces fichiers. De nombreux changements devront être apportés.Pour éviter cela, vous pouvez utiliser des fichiers pouvant être inclus dans d'autres fichiers. Par exemple. Il existe un fichier avec l'en-tête du site. Et si vous devez modifier quelque chose, il suffit alors de modifier un seul fichier, car il se connecte simplement aux autres.
Dans le dossier des modèles de vues, créez un dossier appelé blocs, et dedans le fichier hrader.ejs.
Fichier hrader.ejs
- Au principal
- À propos de nous
- Nouvelles
Nous devons maintenant inclure ce fichier dans tous les modèles. Accédez au fichier d'actualités et immédiatement après la balise body d'ouverture, écrivez :
<% include blocks/header.ejs %>
Le chemin est spécifié à partir du dossier des vues, puisque le moteur de modèles commence toujours à chercher à cet endroit.
Fichiers statiques.
Créons un nouveau dossier au niveau index.js appelé public. Il contiendra tous les fichiers statiques. Ce sont des fichiers CSS, des images, des documents, etc. Tous ces fichiers. qui sera appelé depuis différentes pages de notre site.Dans ce dossier, nous créerons un autre dossier - css et nous y créerons un fichier style.css.
Nous y transférerons tout le code de style du fichier index.ejs
Dans les fichiers .ejs, nous incluons les styles :
Si vous vérifiez maintenant, rien ne se passera. Les styles ne se connecteront pas.
Pour inclure des fichiers statiques, nous devons utiliser un middleware :
Dans le fichier index.js en haut, juste après app.set , il faut écrire :
App.use("/public",);
Et maintenant, si nous utilisons un lien quelque part commençant par /public, NodeJS et Express lui-même comprendront ce que nous utilisons fichiers statiques et tout se connectera correctement.
La seconde est l'endroit où nous les recherchons express.static("public"), c'est-à-dire dans le dossier /public.
Pour résumer, dans le code app.use("/public", express.static("public")); nous suivons le lien dans lequel nous écrivons
Si c'était comme ça :
Alors dans ce code ce serait :
App.use("/assets", express.static("public"));
Dans ce cas, public pointe vers un dossier !
Si vous le laissez ainsi, aucun changement ne se produira. Le fichier sera inclus car nous suivrons le lien des actifs.
App.use("/assets ", express.static("public "));
Afin d'éviter toute confusion, ils créent généralement le lien et le dossier du même nom. Le plus souvent, c'est public.
Le middleware est ce que nous faisons avant d'envoyer des données à la page (serveur).
Dans ce cas, il s'agit de notre middleware.
Création d'un formulaire HTML et récupération de données
La première chose que nous ferons est d'ajouter le formulaire lui-même à notre site.Ouvrez le fichier about.ejs et nous ajouterons ici un formulaire utilisant la technologie bootstrap.
Entrez Forms dans la fenêtre de recherche et copiez le premier formulaire en partant du haut sur la page trouvée.
Sauvons et courons.
Requête POST.
Puisque nous allons effectuer une requête POST, nous devons ajouter plusieurs attributs au formulaire.Method="post" - car requête POST
Et action="" est l'endroit où vous devez rediriger l'utilisateur après avoir cliqué sur "Soumettre". Dans notre cas c'est :
![mob_info](https://mapstr.ru/wp-content/themes/kuzov/pic/mob_info.png)