Γρήγορος διακομιστής Express js. Node JS & Express Basics (III)
$ npm εγκατάσταση express
ή, για να έχετε πρόσβαση στην εντολή express, εγκαταστήστε καθολικά:
$ npm εγκατάσταση -g express
Γρήγορη εκκίνηση
Ο ευκολότερος τρόπος για να ξεκινήσετε με το Express είναι να εκτελέσετε την εντολή express, η οποία θα δημιουργήσει την εφαρμογή:
Δημιουργία εφαρμογής:
$ npm εγκατάσταση -g express $ express /tmp/foo && cd /tmp/foo
Εγκατάσταση εξαρτήσεων:
$ npm εγκατάσταση -d
Εκκίνηση του διακομιστή:
Δημιουργία διακομιστή
Για να δημιουργήσετε μια παρουσία του express.HTTPServer, απλώς καλέστε τη μέθοδο createServer(). Με την παρουσία της εφαρμογής μας, μπορούμε να καθορίσουμε διαδρομές με βάση τις μεθόδους HTTP, σε αυτό το παράδειγμα app.get() .
var app = require("express").createServer(); app.get("/", function(req, res)( res.send("hello world"); )); app.listen(3000);
Δημιουργία διακομιστή HTTPS
Για να αρχικοποιήσουμε το express.HTTPSServer , εκτελούμε τα ίδια βήματα όπως παραπάνω, αλλά μεταβιβάζουμε επίσης ένα αντικείμενο επιλογών που περιέχει το κλειδί, το πιστοποιητικό και άλλες παραμέτρους που περιγράφονται στην τεκμηρίωση της λειτουργικής μονάδας NodeJS https.
var app = require("express").createServer(( κλειδί: ... ));
Διαμόρφωση
Η Express υποστηρίζει αυθαίρετα περιβάλλοντα, όπως η παραγωγή και η ανάπτυξη. Οι προγραμματιστές μπορούν να χρησιμοποιήσουν τη μέθοδο configure() για να προσθέσουν λειτουργίες που απαιτούνται για ένα δεδομένο περιβάλλον. Όταν καλείται η configure() χωρίς όνομα περιβάλλοντος, θα ενεργοποιηθεί σε οποιοδήποτε περιβάλλον πριν ενεργοποιηθεί οποιαδήποτε ρύθμιση παραμέτρων στην οποία έχει καθοριστεί το περιβάλλον.
Στο παρακάτω παράδειγμα, χρησιμοποιούμε απλώς την επιλογή dumpExceptions και, στη λειτουργία ανάπτυξης, απαντάμε στον πελάτη με ένα ίχνος στοίβας της εξαίρεσης. Και στις δύο καταστάσεις, χρησιμοποιούμε τα επίπεδα methodOverride και bodyParser. Σημειώστε τη χρήση του app.router , το οποίο από μόνο του επιτρέπει την προσάρτηση διαδρομών - διαφορετικά τοποθετούνται την πρώτη φορά που καλούνται οι app.get() , app.post() κ.λπ.
app.configure(function())( app.use(express.methodOverride()); app.use(express.bodyParser()); app.use(app.router); )); app.configure("ανάπτυξη", λειτουργία())( 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() ) ;));
Για περιβάλλοντα με παρόμοιες ρυθμίσεις, μπορείτε να μεταβιβάσετε πολλά ονόματα περιβάλλοντος:
app.configure("stage", "prod", function())( // config ));
Για εσωτερικές και αυθαίρετες ρυθμίσεις, το Express έχει τις μεθόδους set(key[, val]), enable(key) , disable(key) :
app.configure(function () ( app.set("views", __dirname + "/views"); app.set("views"); // => "/absolute/path/to/views" app.enable ("κάποιο χαρακτηριστικό"); // ίδιο με το app.set ("κάποιο χαρακτηριστικό", true); app.disable ("κάποιο χαρακτηριστικό"); // ίδιο με το app.set ("κάποιο χαρακτηριστικό", false) ; app .enabled("κάποιο χαρακτηριστικό") // => false ));
Για να ορίσουμε το περιβάλλον μπορούμε να ορίσουμε τη μεταβλητή περιβάλλοντος NODE_ENV. Για παράδειγμα:
$ NODE_ENV=παραγωγικός κόμβος app.js
Αυτό είναι πολύ σημαντικό γιατί πολλοί μηχανισμοί προσωρινής αποθήκευσης ενεργοποιούνται μόνο σε περιβάλλον παραγωγής.
Ρυθμίσεις
Out of the box Express υποστηρίζει τις ακόλουθες ρυθμίσεις:
- home είναι η βασική διαδρομή της εφαρμογής, η οποία χρησιμοποιείται για την res.redirect() καθώς και για διαφανή υποστήριξη για προσαρτημένες εφαρμογές.
- views είναι ο ριζικός κατάλογος των προβολών. Από προεπιλογή current_folder/views
- μηχανή προβολής - προεπιλεγμένη μηχανή προτύπων για προβολές που καλούνται χωρίς επέκταση αρχείου.
- επιλογές προβολής - ένα αντικείμενο που αντικατοπτρίζει τις επιλογές καθολικής προβολής
- προβολή προσωρινής μνήμης - ενεργοποίηση προσωρινής αποθήκευσης προβολής (ενεργοποιημένη σε περιβάλλον παραγωγής)
- διαδρομές με διάκριση πεζών-κεφαλαίων - ενεργοποιήστε τις διαδρομές με διάκριση πεζών-κεφαλαίων
- αυστηρή δρομολόγηση - εάν είναι ενεργοποιημένη, οι τελικές κάθετες δεν αγνοούνται πλέον
- jsonp επανάκληση - επιτρέψτε στη μέθοδο res.send() να υποστηρίζει με διαφάνεια το JSONP
Δρομολόγηση
Η Express χρησιμοποιεί μεθόδους HTTP για να παρέχει ένα ουσιαστικό, εκφραστικό API δρομολόγησης. Για παράδειγμα, θέλουμε η αναζήτηση για /user/12 να εμφανίζει το προφίλ του χρήστη με id=12 . Για να γίνει αυτό, ορίζουμε τη διαδρομή παρακάτω. Οι τιμές που σχετίζονται με πεδία με όνομα είναι διαθέσιμες στο αντικείμενο res.params.
app.get("/user/:id", function(req, res)( res.send("user" + req.params.id); ));
Μια διαδρομή είναι απλώς μια συμβολοσειρά που μεταγλωττίζεται σε μια κανονική έκφραση μέσα στον κινητήρα. Για παράδειγμα, όταν μεταγλωττίζεται το /user/:id, το αποτέλεσμα είναι μια τυπική έκφραση όπως αυτή:
\/χρήστης\/([^\/]+)\/?
Μπορείτε επίσης να περάσετε αμέσως μια τυπική έκφραση. Αλλά επειδή οι ομάδες δεν ονομάζονται σε κανονικές εκφράσεις, μπορούν να προσεγγιστούν σε req.params με αριθμούς. Έτσι η πρώτη ομάδα πηγαίνει σε req.params, η δεύτερη σε req.params κ.λπ.
app.get(/^\/χρήστες?(?:\/(\d+)(?:\.\.(\d+))?)?/, function(req, res)( res.send(req.params );));
Τώρα ας πάρουμε το curl και ας στείλουμε ένα αίτημα στην παραπάνω διαδρομή:
$ curl http://dev:3000/user $ curl http://dev:3000/users $ curl http://dev:3000/users/1 ["1",null] $ curl http://dev: 3000/χρήστες/1..15 ["1","15"]
Ακολουθούν μερικά παραδείγματα διαδρομών και μονοπατιών που μπορεί να ταιριάζουν με αυτά:
"/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 "/ user/:id/:operation?" /user/1 /user/1/edit "/products.:format" /products.json /products.xml "/products.:format?" /products.json /products.xml /products "/user/:id.:format?" /user/12 /user/12.json
Για παράδειγμα, μπορούμε να ΑΝΑΡΤΗΣΟΥΜΕ κάποιο JSON και να απαντήσουμε με το ίδιο JSON χρησιμοποιώντας το επίπεδο bodyParser, το οποίο μπορεί να αναλύσει ένα αίτημα JSON (καθώς και άλλα αιτήματα) και να τοποθετήσει την απάντηση στο req.body:
var express = απαιτείται ("express"), app = express.createServer(); app.use(express.bodyParser()); app.post("/", function(req, res) ( res.send(req.body); )); app.listen(3000);
Κατά κανόνα, χρησιμοποιούμε ένα πεδίο "χαζό" (για παράδειγμα, /user/:id), το οποίο δεν έχει περιορισμούς. Αλλά αν, για παράδειγμα, θέλουμε να περιορίσουμε το αναγνωριστικό χρήστη μόνο σε αριθμητικούς χαρακτήρες, μπορούμε να χρησιμοποιήσουμε το /user/:id(+) . Αυτό το σχέδιο δεν θα λειτουργήσει εάν η τιμή του πεδίου περιέχει μη αριθμητικούς χαρακτήρες.
Μεταφορά του ελέγχου σε άλλη διαδρομή
Καλώντας το τρίτο όρισμα, next() , μπορείτε να περάσετε τον έλεγχο στην επόμενη διαδρομή. Εάν δεν βρεθεί αντιστοίχιση, ο έλεγχος επιστρέφει στο Connect και τα επίπεδα συνεχίζουν να καλούνται με τη σειρά με την οποία ενεργοποιήθηκαν χρησιμοποιώντας τη χρήση() . Λειτουργούν επίσης πολλές διαδρομές που μοιράζονται την ίδια διαδρομή. Απλώς καλούνται ένα κάθε φορά έως ότου ένας από αυτούς απαντήσει αντί να καλέσει το next() .
app.get("/users/:id?", function(req, res, next) ( var id = req.params.id; if (id) ( // κάντε κάτι ) other ( next(); ) )) ; app.get("/users", function(req, res) ( // κάντε κάτι άλλο ));
Η μέθοδος app.all() είναι χρήσιμη εάν θέλετε να εκτελέσετε την ίδια λογική για όλες τις μεθόδους HTTP. Παρακάτω χρησιμοποιούμε αυτήν τη μέθοδο για να ανακτήσουμε έναν χρήστη από τη βάση δεδομένων και να τον εκχωρήσουμε στο req.user.
var express = απαιτείται ("express"), app = express.createServer(); var users = [( όνομα: "tj" )]; app.all("/user/:id/:op?", function(req, res, next) ( req.user = users; if (req.user) ( next(); ) other ( next(new Error( "δεν μπορώ να βρω τον χρήστη " + 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("επεξεργασία " + req.user.name); )); app.put("/user/:id", function(req, res) ( res.send("ενημέρωση " + req.user.name); )); app.get("*", function(req, res) ( res.send("what???", 404); )); app.listen(3000);
Ενδιάμεσα στρώματα
Τα επίπεδα πλαισίου σύνδεσης μπορούν να περάσουν στο express.createServer() με τον ίδιο τρόπο όπως εάν χρησιμοποιήθηκε ένας κανονικός διακομιστής Connect. Για παράδειγμα:
var express = απαιτώ ("express"); var app = express.createServer(express.logger(), express.bodyParser());
Μπορείτε επίσης να χρησιμοποιήσετε τη χρήση() . Αυτό καθιστά πιο βολική την προσθήκη επιπέδων μέσα στα μπλοκ configure(), που είναι πιο προοδευτική.
app.use(express.logger(( μορφή: ":method:url" )));
Συνήθως με τα επίπεδα Connect μπορούμε να συνδέσουμε το Connect ως εξής:
var connect = απαιτείται ("σύνδεση"); app.use(connect.logger()); app.use(connect.bodyParser());
Αυτό δεν είναι απολύτως βολικό, επομένως η Express επανεξάγει τα επίπεδα Connect:
app.use(express.logger()); app.use(express.bodyParser());
Η σειρά των στρώσεων έχει σημασία. Έτσι, όταν το Connect λαμβάνει ένα αίτημα, εκτελείται το πρώτο επίπεδο που προστέθηκε μέσω της createServer() ή της use(). Καλείται με τρεις παραμέτρους: αίτημα, απόκριση και συνάρτηση επανάκλησης, που συνήθως καλείται επόμενο. όταν καλείται next(), ο έλεγχος περνά στο δεύτερο επίπεδο, κ.λπ. Αυτό είναι σημαντικό να ληφθεί υπόψη, καθώς πολλά στρώματα εξαρτώνται το ένα από το άλλο. Για παράδειγμα, η methodOverride() καλεί το req.body.method για να υπερφορτώσει μια μέθοδο HTTP και η bodyParser() αναλύει το σώμα του αιτήματος για να συμπληρώσει το req.body . Ένα άλλο παράδειγμα είναι η ανάλυση cookie και η υποστήριξη συνεδρίας - πρώτα πρέπει να καλέσετε τη use() στο cookieParser() και μετά στην session() .
Πολλές εφαρμογές Express μπορεί να έχουν τη γραμμή app.use(app.router) . Αυτό μπορεί να φαίνεται περίεργο, αλλά αυτό είναι απλά για να προσδιορίσουμε ρητά το επίπεδο που περιλαμβάνει όλες τις διαδρομές που δημιουργήσαμε. Αυτό το επίπεδο μπορεί να συμπεριληφθεί με οποιαδήποτε σειρά, αν και από προεπιλογή περιλαμβάνεται στο τέλος. Αλλάζοντας τη θέση του, μπορείτε να ελέγξετε τη σειρά εκτέλεσής του. Για παράδειγμα, χρειαζόμαστε ένα πρόγραμμα χειρισμού σφαλμάτων που θα ενεργοποιείται μετά από όλα τα άλλα επίπεδα και θα εμφανίζει οποιαδήποτε εξαίρεση μεταβιβάζεται σε αυτόν χρησιμοποιώντας το next() . Ή μπορεί να είναι απαραίτητο να χαμηλώσετε τη σειρά εκτέλεσης του επιπέδου που εξυπηρετεί στατικά αρχεία για να επιτρέψετε σε άλλες διαδρομές να υποκλέψουν αιτήματα για τέτοια αρχεία και, για παράδειγμα, να μετρήσουν τον αριθμό των λήψεων κ.λπ. Δείτε πώς μπορεί να μοιάζει:
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(...));
Πρώτα προσθέτουμε το logger() - θα τυλίξει τη μέθοδο req.end() για να μας δώσει δεδομένα ρυθμού απόκρισης. Στη συνέχεια, αναλύουμε το σώμα του αιτήματος (αν υπάρχει), μετά τα cookies και μετά τη συνεδρία, έτσι ώστε η req.session να είναι ήδη καθορισμένη όταν φτάσουμε στις διαδρομές στο app.router . Εάν, για παράδειγμα, ένα αίτημα GET στο /javascripts/jquery.js αντιμετωπίζεται από διαδρομές και δεν καλέσουμε το next() , τότε το επίπεδο static() δεν θα λάβει ποτέ αυτό το αίτημα. Ωστόσο, εάν ορίσουμε μια διαδρομή όπως φαίνεται παρακάτω, θα είναι δυνατή η καταγραφή στατιστικών στοιχείων, η απόρριψη λήψεων, η χρέωση λήψεων κ.λπ.
var λήψεις = (); app.use(app.router); app.use(express.static(__dirname + "/public")); app.get("/*", function(req, res, next) ( var file = req.params; λήψεις = λήψεις || 0; downloads++; next(); ));
Διαδρομές στρώσεων
Οι διαδρομές μπορούν να χρησιμοποιήσουν επίπεδα δρομολόγησης περνώντας πρόσθετες επανακλήσεις (ή πίνακες) στη μέθοδο. Αυτό είναι χρήσιμο εάν πρέπει να περιορίσετε την πρόσβαση ή να φορτώσετε δεδομένα πριν χρησιμοποιήσετε μια διαδρομή κ.λπ.
Συνήθως, η ασύγχρονη ανάκτηση δεδομένων μπορεί να μοιάζει με αυτήν που φαίνεται παρακάτω (εδώ παίρνουμε την παράμετρο:id και φορτώνουμε τα δεδομένα χρήστη).
app.get("/user/:id", function(req, res, next) ( loadUser(req.params.id, function(err, user) ( if (err) return next(err); res.send( "Προβολή χρήστη " + user.name); )); ));
Για να τηρήσετε την αρχή DRY και να βελτιώσετε την αναγνωσιμότητα του κώδικα, μπορείτε να οργανώσετε μια τέτοια λογική χρησιμοποιώντας επίπεδα. Όπως μπορείτε να δείτε, αφαιρώντας τη λογική χρησιμοποιώντας επίπεδα, μπορείτε να επιτύχετε την επαναχρησιμοποίηση των επιπέδων και να κάνετε τον κώδικα διαδρομής πιο όμορφο.
συνάρτηση loadUser(req, res, next) ( // εδώ φορτώνουμε τον χρήστη από τη βάση δεδομένων var user = users; if (user) ( req.user = user; next(); ) else ( next(new Error("Failed για φόρτωση χρήστη " + req.params.id)); ) ) app.get("/user/:id", loadUser, function(req, res) ( res.send("Προβολή χρήστη" + req.user.name ) ;));
Μπορούν να προστεθούν πολλαπλά επίπεδα δρομολόγησης και θα εκτελεστούν διαδοχικά για να παρέχουν διαφορετική λογική, όπως τον περιορισμό της πρόσβασης σε έναν λογαριασμό χρήστη. Στο παρακάτω παράδειγμα, μόνο ένας εξουσιοδοτημένος χρήστης μπορεί να επεξεργαστεί τον λογαριασμό του.
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("Επεξεργασία χρήστη " + req.user.name); ));
Αναγνωρίζοντας ότι τα επίπεδα είναι απλώς συναρτήσεις, μπορείτε να γράψετε μια συνάρτηση που επιστρέφει ένα επίπεδο (για να παρέχει μια ακόμη πιο εκφραστική και ευέλικτη λύση), όπως φαίνεται παρακάτω.
function andRestrictTo(role) ( return function(req, res, next) ( req.authenticatedUser.role == ρόλος ? next() : next(new Error("Unauthorized")); ) ) app.del("/user/ :id", loadUser, andRestrictTo("admin"), function(req, res) ( res.send("Deleted user " + req.user.name); ));
Οι συχνά χρησιμοποιούμενες «στοίβες» στρωμάτων μπορούν να περάσουν ως πίνακες αυθαίρετου βάθους και δομής δέντρου (θα εφαρμοστούν αναδρομικά):
var a = , b = , όλα = ; 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() ());
Το πλήρες παράδειγμα μπορεί να προβληθεί στο αποθετήριο.
Υπάρχουν φορές που πρέπει να παραλείψετε τα υπόλοιπα επίπεδα διαδρομής στη στοίβα, αλλά να συνεχίσετε να εκτελείτε τις επόμενες διαδρομές. Για να το κάνετε αυτό, καλέστε το next() με το όρισμα διαδρομής: next("route") . Εάν δεν έχουν απομείνει διαδρομές για εκτέλεση, η Express θα απαντήσει με ένα σφάλμα 404 Not Found.
Μέθοδοι HTTP
Έχουμε ήδη χρησιμοποιήσει το app.get() πολλές φορές, αλλά το Express παρέχει επίσης άλλες μεθόδους HTTP - app.post() , app.del() κ.λπ.
Η πιο συνηθισμένη περίπτωση χρήσης του POST είναι κατά την υποβολή μιας φόρμας. Στο παρακάτω παράδειγμα φτιάχνουμε απλώς μια φόρμα HTML. Και μετά ο έλεγχος θα μεταφερθεί στη διαδρομή που θα ορίσουμε στο επόμενο παράδειγμα.
Από προεπιλογή, η Express δεν ξέρει τι να κάνει με το σώμα του αιτήματος, επομένως πρέπει να προσθέσουμε ένα επίπεδο bodyParser() που θα αναλύει το σώμα αιτήματος που είναι κωδικοποιημένο στο application/x-www-form-urlencoded ή στο application/json και να βάλει το η ανάλυση έχει ως αποτέλεσμα την απαίτηση .σώμα. Για να γίνει αυτό πρέπει να πούμε use() όπως παρακάτω:
app.use(express.bodyParser());
Τώρα η παρακάτω διαδρομή θα έχει πρόσβαση στο αντικείμενο req.body.user, το οποίο θα έχει ιδιότητες ονόματος και email:
app.post("/", function(req, res) ( console.log(req.body.user); res.redirect("πίσω"); ));
Εάν η φόρμα χρησιμοποιεί μεθόδους όπως το PUT, μπορείτε να χρησιμοποιήσετε μια κρυφή είσοδο που ονομάζεται _method, η οποία σας επιτρέπει να αλλάξετε τη μέθοδο HTTP. Για να το πετύχουμε αυτό, πρέπει πρώτα να ενεργοποιήσουμε ένα επίπεδο methodOverride(), το οποίο θα τοποθετηθεί μετά το bodyParser(), το οποίο θα του επιτρέψει να χρησιμοποιήσει το req.body που περιέχει τα πεδία της υποβληθείσας φόρμας.
app.use(express.bodyParser()); app.use(express.methodOverride());
Αυτά τα επίπεδα δεν είναι ενεργοποιημένα από προεπιλογή, επειδή το Express δεν έχει απαραίτητα πλήρη λειτουργικότητα αμέσως. Ανάλογα με τις ανάγκες της εφαρμογής, μπορεί να μην χρειαστεί να τα χρησιμοποιήσετε. Και τότε οι μέθοδοι PUT και DELETE θα εξακολουθούν να είναι διαθέσιμες, αλλά απευθείας. Ταυτόχρονα, το methodOverride είναι μια εξαιρετική λύση για φόρμες HTML. Ακολουθεί ένα παράδειγμα χρήσης της μεθόδου PUT:
app.put("/", function() ( console.log(req.body.user); res.redirect("πίσω"); ));Σφάλμα επεξεργασίας
Η Express διαθέτει μια μέθοδο app.error() που δέχεται τυχόν εξαιρέσεις που προκύπτουν από διαδρομές ή μεταβιβάζονται ως επόμενο(err) . Ακολουθεί ένα παράδειγμα του τρόπου προβολής πολλαπλών σελίδων χρησιμοποιώντας μια σπιτική εξαίρεση NotFound:
συνάρτηση 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) (ρίξε νέο NotFound; )); app.get("/500", function(req, res) ( ρίχνει νέο Σφάλμα ("keyboard cat!"); ));
Μπορείτε να καλέσετε το app.error() πολλές φορές όπως φαίνεται παρακάτω. Εδώ ελέγχουμε το instanceof NotFound και εμφανίζουμε μια σελίδα 404 ή περνάμε τον έλεγχο στον επόμενο χειριστή σφαλμάτων.
Σημειώστε ότι αυτοί οι χειριστές μπορούν να οριστούν οπουδήποτε, καθώς θα εξακολουθούν να βρίσκονται κάτω από τους χειριστές διαδρομής στο listen() . Αυτό τους επιτρέπει να ορίζονται μέσα σε μπλοκ configure(), έτσι ώστε οι εξαιρέσεις να μπορούν να αντιμετωπίζονται διαφορετικά ανάλογα με το τρέχον περιβάλλον.
app.error(function(err, req, res, next) ( if (er instanceof NotFound) ( res.render("404.jade"); ) else ( next(err); ) ));
Για λόγους απλότητας, υποθέτουμε εδώ ότι όλα τα σφάλματα έχουν κωδικό 500, αλλά μπορείτε να τον αλλάξετε όπως θέλετε. Για παράδειγμα, όταν το Node εκτελεί λειτουργίες συστήματος αρχείων, μπορούμε να λάβουμε ένα αντικείμενο σφάλματος με πεδίο error.code = ENOENT, που σημαίνει "αρχείο ή κατάλογος δεν βρέθηκε", μπορούμε να το χρησιμοποιήσουμε σε ένα πρόγραμμα χειρισμού σφαλμάτων και να εμφανίσουμε την αντίστοιχη σελίδα.
app.error(function(err, req, res) ( res.render("500.jade", ( error: err )); ));
Οι εφαρμογές μπορούν επίσης να χρησιμοποιήσουν το επίπεδο errorHander του Connect για να χειριστούν εξαιρέσεις. Για παράδειγμα, εάν πρέπει να εμφανίσετε εξαιρέσεις στο stderr στο περιβάλλον ανάπτυξης, μπορείτε να το κάνετε αυτό:
app.use(express.errorHandler(( dumpExceptions: true )));
Επίσης, κατά την ανάπτυξη, μπορεί να χρειαστούμε ενδιαφέρουσες σελίδες HTML που εμφανίζουν εξαιρέσεις που έχουν πεταχτεί ή πεταχτεί. Σε αυτήν την περίπτωση, πρέπει να ορίσετε το showStack σε true:
app.use(express.errorHandler(( showStack: true, dumpExceptions: true )));
Το επίπεδο errorHandler ανταποκρίνεται επίσης σε JSON εάν μια κεφαλίδα Accept: application/json περάσει από τον πελάτη, η οποία είναι χρήσιμη για την ανάπτυξη εφαρμογών AJAX.
Προεπεξεργασία παραμέτρων διαδρομής
Η προεπεξεργασία των παραμέτρων διαδρομής μπορεί να βελτιώσει σημαντικά την αναγνωσιμότητα μιας εφαρμογής μέσω της ρητής φόρτωσης δεδομένων και της επικύρωσης URL αιτήματος. Για παράδειγμα, εάν ανακτάτε συνεχώς κάποια δεδομένα για ορισμένα ερωτήματα (π.χ. φορτώνετε δεδομένα χρήστη για το /user/:id), θα μπορούσατε να κάνετε κάτι σαν αυτό:
app.get("/user/:userId", function(req, res, next) ( User.get(req.params.userId, function(err, user) ( if (err) return next(err); res. send("user" + user.name); )); ));
Με προϋποθέσεις, μπορούμε να επισυνάψουμε συναρτήσεις επανάκλησης στις παραμέτρους του ερωτήματός μας που θα εκτελούν επικύρωση, θα περιορίζουν την πρόσβαση ή ακόμη και θα φορτώνουν δεδομένα από τη βάση δεδομένων. Στο παρακάτω παράδειγμα, καλούμε την app.param() με το όνομα της παραμέτρου στην οποία θέλουμε να επισυνάψουμε μια επιστροφή κλήσης. Όπως μπορείτε να δείτε, λαμβάνουμε ένα όρισμα id, το οποίο περιέχει το όνομα του πεδίου. Με αυτόν τον τρόπο φορτώνουμε το αντικείμενο χρήστη και κάνουμε τον συνήθη χειρισμό σφαλμάτων και μια απλή κλήση στο next() για να περάσουμε τον έλεγχο στον επόμενο χειριστή προϋποθέσεων ή διαδρομής.
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("απέτυχε η εύρεση χρήστη")); req.user = χρήστης; next(); )); ));
Τα παραπάνω βήματα, όπως ήδη αναφέρθηκε, βελτιώνουν σημαντικά την αναγνωσιμότητα του κώδικα και διευκολύνουν τη χρήση της ίδιας λογικής σε διαφορετικά σημεία της εφαρμογής:
app.get("/user/:userId", function(req, res) ( res.send("user" + req.user.name); ));
Απόδοση προβολών
Προβολή ονομάτων αρχείων ακολουθεί το σχήμα (όνομα). (κινητήρας), όπου (κινητήρας) είναι το όνομα της μονάδας προτύπου κινητήρα που πρέπει να συνδεθεί. Για παράδειγμα, η προβολή layout.ejs λέει στο σύστημα προβολής να κάνει require("ejs") . Για να ενσωματωθεί στο Express, η μονάδα με δυνατότητα φόρτωσης πρέπει να εξάγει μια μέθοδο, το exports.compile(str, options) και να επιστρέψει μια συνάρτηση. Για να αλλάξετε αυτήν τη συμπεριφορά, μπορείτε να χρησιμοποιήσετε τη μέθοδο app.register() - σας επιτρέπει να συσχετίσετε επεκτάσεις αρχείων με συγκεκριμένους κινητήρες. Για παράδειγμα, μπορείτε να δημιουργήσετε το foo.html που αποδίδεται από τη μηχανή ejs.
Παρακάτω είναι ένα παράδειγμα χρήσης Νεφρίτηςγια απόδοση index.html . Και επειδή δεν χρησιμοποιούμε layout:false , το περιεχόμενο που αποδίδεται στην προβολή index.jade θα μεταβιβαστεί ως μεταβλητή τοπικού σώματος στην προβολή layout.jade.
app.get("/", function(req, res) ( res.render("index.jade", ( title: "My Site" )); ));
Η ρύθμιση της μηχανής προβολής σάς επιτρέπει να καθορίσετε την προεπιλεγμένη μηχανή προτύπων. Έτσι, για παράδειγμα, όταν χρησιμοποιείτε το Jade μπορείτε να κάνετε αυτό:
app.set("view engine", "jade");
που θα μας επιτρέψει να αποδώσουμε ως εξής:
res.render("index");
Όχι όμως έτσι:
res.render("index.jade");
Όταν η μηχανή προτύπων εγκαθίσταται μέσω της μηχανής προβολής, δεν χρειάζονται επεκτάσεις αρχείων. Ωστόσο, μπορούμε ακόμα να χρησιμοποιήσουμε πολλές μηχανές προτύπων ταυτόχρονα:
res.render("another-page.ejs");
Το Express έχει επίσης μια ρύθμιση επιλογών προβολής που θα εφαρμόζεται κάθε φορά που αποδίδεται η προβολή. Για παράδειγμα, εάν δεν χρησιμοποιείτε τόσο συχνά διατάξεις, μπορείτε να το γράψετε ως εξής:
app.set("προβολή επιλογών", ( διάταξη: ψευδής ));
Το οποίο μπορεί στη συνέχεια να υπερφορτωθεί εάν είναι απαραίτητο σε μια κλήση στη res.render():
res.render("myview.ejs", ( διάταξη: true ));
Όταν χρειάζεστε διαφορετική διάταξη, μπορείτε επίσης να καθορίσετε τη διαδρομή. Για παράδειγμα, εάν έχουμε τη μηχανή προβολής ρυθμισμένη σε jade και το αρχείο διάταξης ονομάζεται ./views/mylayout.jade, μπορούμε απλά να περάσουμε:
res.render("σελίδα", ( διάταξη: "mylayout" ));
Διαφορετικά, μπορείτε να περάσετε την επέκταση αρχείου:
res.render("σελίδα", ( διάταξη: "mylayout.jade" ));
Οι διαδρομές μπορούν επίσης να είναι απόλυτες:
res.render("σελίδα", ( διάταξη: __dirname + "/../../mylayout.jade" ));
Ένα καλό παράδειγμα είναι ο καθορισμός μη τυπικών ετικετών ανοίγματος και κλεισίματος κινητήρα ejs:
app.set("προβολή επιλογών", ( άνοιγμα: "((", κλείσιμο: "))" ));
Προβολή θραυσμάτων
Το σύστημα Express view έχει ενσωματωμένη υποστήριξη για θραύσματα και συλλογές, ένα είδος μίνι προβολής. Για παράδειγμα, αντί να κάνετε κύκλο στην προβολή για να εμφανίσετε μια λίστα σχολίων, μπορείτε απλώς να χρησιμοποιήσετε ένα τμήμα συλλογής:
partal("σχόλιο", (συλλογή: σχόλια));
Εάν δεν χρειάζονται άλλες επιλογές ή τοπικές μεταβλητές, τότε μπορείτε να παραλείψετε το αντικείμενο και απλώς να περάσετε τον πίνακα δεδομένων. Το παρακάτω παράδειγμα είναι ισοδύναμο με το προηγούμενο:
partal("σχόλιο", σχόλια);
Όταν χρησιμοποιούμε συλλογές, έχουμε αρκετές «μαγικές» τοπικές μεταβλητές:
- firstInCollection - true αν αυτό είναι το πρώτο αντικείμενο
- indexInCollection - ευρετήριο του αντικειμένου στη συλλογή
- lastInCollection - true αν αυτό είναι το τελευταίο αντικείμενο
- συλλογήΜήκος - μήκος συλλογής
Οι τοπικές μεταβλητές που μεταβιβάζονται ή δημιουργούνται έχουν προτεραιότητα, αλλά οι τοπικές μεταβλητές που μεταβιβάζονται στη γονική προβολή είναι επίσης διαθέσιμες στη θυγατρική προβολή. Έτσι, για παράδειγμα, εάν αποδώσουμε μια προβολή χρησιμοποιώντας partal("blog/post", post) και παράγει μια τοπική μεταβλητή ανάρτηση , και η προβολή που κάλεσε αυτήν τη συνάρτηση είχε έναν τοπικό χρήστη μεταβλητής, τότε ο χρήστης θα είναι επίσης ορατός στο ιστολόγιο /προβολή ανάρτησης.
Δείτε res.partial() για περισσότερη τεκμηρίωση.
Σημείωση: Χρησιμοποιήστε τις συλλογές προσεκτικά, καθώς η απόδοση ενός πίνακα 100 στοιχείων σημαίνει απόδοση 100 προβολών. Για απλές συλλογές, είναι προτιμότερο να κάνετε κύκλο μέσα από την προβολή αντί να χρησιμοποιείτε συλλογές. Έτσι το φορτίο θα είναι μικρότερο.
Αναζήτηση για προβολές
Οι προβολές αναζητούνται σε σχέση με τη γονική προβολή. Για παράδειγμα, εάν έχουμε μια προβολή views/user/list.jade και μέσα σε αυτήν ονομάζουμε partal("edit") , το σύστημα θα προσπαθήσει να φορτώσει την προβολή views/user/edit.jade , ενώ μερική("../ μηνύματα") θα έχει ως αποτέλεσμα τη λήψη του views/messages.jade
Το σύστημα προβολής σάς επιτρέπει επίσης να δημιουργείτε αρχεία ευρετηρίου. Για παράδειγμα, μπορούμε να καλέσουμε το res.render("users") και αυτό μπορεί να φορτώσει τόσο το views/users.jade όσο και το views/users/index.jade .
Μπορείτε επίσης να χρησιμοποιήσετε αρχεία ευρετηρίου από μια προβολή στον ίδιο κατάλογο. Έτσι, η κλήση μερικού("χρήστες") μπορεί να έχει πρόσβαση στην προβολή ../users/index αντί για κλήση μερικής("ευρετήριο") .
Μηχανές προτύπων
Παρακάτω είναι μερικοί κινητήρες προτύπων που χρησιμοποιούνται συνήθως με το Express:
- E.J.S.- ενσωματωμένη JavaScript
- CoffeeKup- με βάση το πρότυπο CoffeeScript
- Πρότυπα jQueryγια τον Κόμβο
Υποστήριξη συνεδρίας
Η υποστήριξη συνεδρίας μπορεί να ενεργοποιηθεί χρησιμοποιώντας το επίπεδο συνεδρίας του Connect. Επίσης για αυτό χρειαζόμαστε ένα υπερκείμενο επίπεδο cookieParser, το οποίο θα αναλύει τα cookies και θα τα τοποθετεί στα req.cookies.
app.use(express.cookieParser()); app.use(express.session(( secret: "keyboard cat" )));
Από προεπιλογή, το επίπεδο περιόδου λειτουργίας χρησιμοποιεί την αποθήκευση στη μνήμη του Connect, αλλά υπάρχουν πολλές άλλες λύσεις. Για παράδειγμα συνδέω-redisυποστηρίζει αποθήκευση συνεδρίας σε Redis. Δείτε πώς να το χρησιμοποιήσετε:
var RedisStore = απαιτείται ("connect-redis")(express); app.use(express.cookieParser()); app.use(express.session(( secret: "keyboard cat", store: new RedisStore )));
Τώρα οι ιδιότητες req.session και req.sessionStore θα είναι διαθέσιμες από όλες τις διαδρομές και τα επόμενα επίπεδα. Οι ιδιότητες req.session αποθηκεύονται αυτόματα κατά την απόκριση. Δείτε πώς να οργανώσετε το καλάθι σας:
var RedisStore = απαιτείται ("connect-redis")(express); app.use(express.bodyParser()); app.use(express.cookieParser()); app.use(express.session(( secret: "keyboard cat", store: new RedisStore ))); app.post("/add-to-cart", function(req, res) ( // ας πούμε ότι περάσαμε πολλά αντικείμενα από τη φόρμα // use bodyParser() για αυτό το var items = req.body.items; req. στοιχεία = στοιχεία; res.redirect("πίσω"); )); app.get("/add-to-cart", function(req, res) ( // Όταν ανακατευθύνουμε στο GET /add-to-cart // μπορούμε να ελέγξουμε req.session.items && req.session.items . μήκος // για να εκτυπώσουμε το μήνυμά μας εάν (req.session.items && req.session.items.length) ( req.flash("info", "Έχετε %s αντικείμενα στο καλάθι σας", req.session.items. μήκος ); ) res.render("καλάθι αγορών"); ));
Το αντικείμενο req.session διαθέτει επίσης μεθόδους Session.touch() , Session.destroy() , Session.regenerat() για τον χειρισμό των περιόδων σύνδεσης. Για πιο ολοκληρωμένες πληροφορίες, ανατρέξτε στην τεκμηρίωση της συνεδρίας σύνδεσης.
Οδηγός Μετανάστευσης
Οι προγραμματιστές που έχουν εργαστεί με το Express 1.x μπορούν να ανατρέξουν στον οδηγό μετεγκατάστασης για να λειτουργήσουν οι εφαρμογές τους με τα Express 2.x, Connect 1.x και Node 0.4.x.
Αίτηση
req.header(key[, defaultValue])
Λάβετε την κεφαλίδα αιτήματος κλειδιού (χωρίς διάκριση πεζών-κεφαλαίων) με μια προαιρετική προεπιλεγμένη τιμή DefaultValue:
req.header("Host"); req.header("host"); req.header("Accept", "*/*");
Οι κεφαλίδες Referrer και Referer είναι μια ειδική περίπτωση· και οι δύο δομές θα λειτουργούν:
// έστειλε την κεφαλίδα "Referrer: http://google.com" req.header("Referer"); // => "http://google.com" req.header("Referrer"); // => "http://google.com"
req.accepts(τύπος)
Ελέγχει εάν η κεφαλίδα Αποδοχή έχει περάσει και αν ταιριάζει με τον συγκεκριμένο τύπο.
Όταν λείπει η κεφαλίδα Αποδοχή, επιστρέφεται το true. Διαφορετικά, ο τύπος ταιριάζει και στη συνέχεια ελέγχονται οι υποτύποι. Είναι δυνατή η μετάδοση "html" που μετατρέπεται εσωτερικά σε "text/html" χρησιμοποιώντας έναν πίνακα αναζήτησης MIME.
// Αποδοχή: text/html req.accepts("html"); // => true // Accept: text/*; application/json req.accepts("html"); req.accepts("text/html"); req.accepts("κείμενο/απλό"); req.accepts("application/json"); // => true req.accepts("image/png"); req.accepts("png"); // => ψευδής
req.is (τύπος)
Ελέγχει το εισερχόμενο αίτημα για την παρουσία κεφαλίδας τύπου περιεχομένου και ταιριάζει με τον καθορισμένο τύπο MIME.
// Αφήστε το Content-Type: text/html; charset=utf-8 req.is("html"); req.is ("κείμενο/html"); // => true // Έστω τώρα το Content-Type application/json req.is("json"); req.is("application/json"); // => true req.is("html"); // => ψευδής
Στο Express, μπορείτε να καταχωρίσετε τις δικές σας επανακλήσεις για διάφορους ελέγχους αιτημάτων. Για παράδειγμα, ας υποθέσουμε ότι πρέπει να κάνουμε έναν καλό έλεγχο για να δούμε αν το εισερχόμενο αίτημα είναι εικόνα. Για να το κάνετε αυτό, μπορείτε να καταχωρήσετε την επιστροφή κλήσης "μια εικόνα":
app.is("μια εικόνα", συνάρτηση(req) ( return 0 == req.headers["content-type"].indexOf("image"); ));
Τώρα μπορείτε να το χρησιμοποιήσετε μέσα στους χειριστές διαδρομής για να ελέγξετε τον Τύπο περιεχομένου της φόρμας "image/jpeg", "image/png" κ.λπ.
app.post("/image/upload", function(req, res, next) ( if (req.is("μια εικόνα")) ( // εκτελέσει ορισμένες ενέργειες ) else ( next(); ) ));
Μην ξεχνάτε ότι αυτή η μέθοδος δεν ισχύει μόνο για το Content-Type - μπορείτε να κάνετε κάθε είδους έλεγχο.
Μπορείτε επίσης να χρησιμοποιήσετε χαρακτήρες μπαλαντέρ. Αυτό θα απλοποιήσει το παράδειγμα εικόνας μας. Εδώ θα ελέγξουμε μόνο τον τύπο:
req.is ("εικόνα/*");
Μπορούμε επίσης να ελέγξουμε τον υποτύπο όπως φαίνεται παρακάτω. Εδώ ο έλεγχος θα επιστρέψει true στις περιπτώσεις "application/json" και "text/json" .
req.is ("*/json");
req.param(όνομα[, προεπιλογή])
Επιστρέφει την τιμή του ονόματος της παραμέτρου ή - εάν δεν υπάρχει - προεπιλογή.
Ελέγχει τις παραμέτρους διαδρομής (req.params), για παράδειγμα /user/:id
Ελέγχει τις παραμέτρους συμβολοσειράς ερωτήματος (req.query), για παράδειγμα, ?id=12
Ελέγχει τις urlencoded παραμέτρους του σώματος αιτήματος (req.body), για παράδειγμα, id=12
Για να λάβετε παραμέτρους σώματος αιτήματος με urlencoded, πρέπει να υπάρχει ένα αντικείμενο req.body. Για να το κάνετε αυτό, ενεργοποιήστε το επίπεδο bodyParser().
req.get(πεδίο, παράμετρος)
Λαμβάνει την παράμετρο πεδίου κεφαλίδας. Η προεπιλογή είναι μια κενή συμβολοσειρά.
req.get("content-disposition", "filename"); // => "something.png" req.get("Content-Type", "boundary"); // => "--foo-bar-baz"
req.flash(τύπος[, msg])
Ουρά το αναδυόμενο μήνυμα.
req.flash("πληροφορίες", "στάλθηκε email"); req.flash("σφάλμα", "αποτυχία παράδοσης email"); req.flash("πληροφορίες", "email επαναστάλθηκε"); // => 2 req.flash("πληροφορίες"); // => ["email εστάλη", "email re-sent"] req.flash("πληροφορίες"); // => req.flash(); // => ( σφάλμα: ["αποτυχία παράδοσης email"], πληροφορίες: )
Τα αναδυόμενα μηνύματα μπορούν επίσης να χρησιμοποιούν συμβολοσειρές μορφής. Η προεπιλεγμένη συμβολοσειρά "%s" είναι διαθέσιμη:
req.flash("πληροφορίες", "η παράδοση email στο _%s_ από _%s_ απέτυχε.", toUser, fromUser);
req.isXMLHttpΑίτηση
Επίσης συντομογραφία req.xhr. Ελέγχει την κεφαλίδα X-Requested-With για να δει αν το αίτημα έγινε χρησιμοποιώντας ένα XMLHttpRequest:
req.xhr req.isXMLHttpΑίτηση
Απάντηση
res.header(key[, val])
Λαμβάνει ή ορίζει την κεφαλίδα απόκρισης.
res.header("Content-Length"); // => undefined res.header("Content-Length", 123); // => 123 res.header("Content-Length"); // => 123
res.charset
Ορίζει την κωδικοποίηση των ακόλουθων κεφαλίδων Τύπου περιεχομένου. Για παράδειγμα, η res.send() και η res.render() θα είναι από προεπιλογή "utf8" και μπορούμε να ορίσουμε ρητά την κωδικοποίηση πριν από την απόδοση του προτύπου:
res.charset = "ISO-8859-1"; res.render("χρήστες");
ή πριν απαντήσετε με res.send():
res.charset = "ISO-8859-1"; res.send(str);
ή χρησιμοποιώντας την ενσωματωμένη res.end() του Node:
res.charset = "ISO-8859-1"; res.header("Content-Type", "text/plain"); res.end(str);
res.contentType(type)
Ορίζει την κεφαλίδα απόκρισης τύπου περιεχομένου.
var όνομα αρχείου = "path/to/image.png"; res.contentType(όνομα αρχείου); // Content-Type είναι πλέον "image/png"
Μπορείτε επίσης να ορίσετε Content-Type με την ακόλουθη συμβολοσειρά:
res.contentType("application/json");
Ή απλώς την επέκταση αρχείου (χωρίς την κύρια κουκκίδα):
res.contentType("json");
res.attachment()
Ορίζει την κεφαλίδα απόκρισης Content-Disposition σε "συνημμένο" . Προαιρετικά, μπορεί να μεταβιβαστεί ένα όνομα αρχείου.
res.attachment("path/to/my/image.png");
res.sendfile(διαδρομή[, επιλογές[, επιστροφή κλήσης]])
Χρησιμοποιείται στο res.download() για τη μεταφορά ενός αυθαίρετου αρχείου.
res.sendfile("path/to/my.file");
Αυτή η μέθοδος λαμβάνει μια προαιρετική παράμετρο επανάκλησης, η οποία καλείται εάν η μεταφορά αρχείου αποτύχει ή επιτύχει. Από προεπιλογή, καλείται το next(err), αλλά αν περάσει η επανάκληση, τότε αυτό πρέπει να γίνει ρητά ή να χειριστεί το σφάλμα.
res.sendfile(path, function(err) ( if (err) ( next(err); ) else (consol.log("transferred %s", path); ) ));
Μπορείτε επίσης να μεταβιβάσετε επιλογές στην κλήση fs.createReadStream(). Για παράδειγμα, για να αλλάξετε το μέγεθος του buffer:
res.sendfile(path, ( bufferSize: 1024 ), function(err) ( // processing... ));
res.download(αρχείο[, όνομα αρχείου[, επανάκληση[, επανάκληση2]]])
Μεταφορτώστε αυτό το αρχείο ως συνημμένο (μπορείτε να καθορίσετε ένα προαιρετικό εναλλακτικό όνομα αρχείου).
res.download('path/to/image.png');
res.download('path/to/image.png', 'foo.png');
Αυτό ισοδυναμεί με το εξής:
res.attachment(αρχείο); res.sendfile(αρχείο);
Προαιρετικά, μπορείτε να καθορίσετε μια επιστροφή κλήσης ως δεύτερο ή τρίτο όρισμα για το res.sendfile() . Μέσα σε αυτό, μπορείτε να απαντήσετε σαν να μην είχε μεταδοθεί ακόμη η κεφαλίδα.
res.download(path, "expenses.doc", function(err) ( // processing... ));
Μπορείτε επίσης να περάσετε προαιρετικά μια δεύτερη επανάκληση - επανάκληση2. Διαχειρίζεται σφάλματα που σχετίζονται με τη σύνδεση. Ωστόσο, δεν πρέπει να επιχειρήσει να στείλει απάντηση.
res.download(διαδρομή, συνάρτηση(er) ( // σφάλμα ή τερματισμός), συνάρτηση(err) ( // σφάλμα σύνδεσης ));
res.send(body|status[, headers|status[, status]])
Η μέθοδος res.send() είναι μια διευκόλυνση απόκρισης υψηλού επιπέδου που σας επιτρέπει να μεταβιβάζετε αντικείμενα (για απάντηση JSON), συμβολοσειρές (για απάντηση HTML), στιγμιότυπα buffer ή ακέραιους αριθμούς που καθορίζουν έναν κωδικό κατάστασης (404, 500, κ.λπ. .) . Δείτε πώς χρησιμοποιείται:
res.send(); // 204 res.send(new Buffer("wahoo")); res.send(( some: "json" )); res.send(""); res.send("Συγγνώμη, δεν μπορώ να το βρω", 404); res.send("text", ( "Content-Type": "text/plain" ), 201); res.send(404);
Από προεπιλογή, η κεφαλίδα Content-Type ορίζεται αυτόματα. Ωστόσο, εάν ορίστηκε ρητά με μη αυτόματο τρόπο στη res.send() ή πριν από τη χρήση της res.header() , ή τη χρήση της res.contentType() , τότε δεν θα οριστεί αυτόματα.
Σημειώστε ότι αυτή η μέθοδος τερματίζει την απόκριση (παρόμοια με την res.end()), επομένως εάν χρειάζεται να δημιουργήσετε πολλές απαντήσεις ή μια ροή, πρέπει να χρησιμοποιήσετε την res.write() .
res.json(obj[, κεφαλίδες|κατάσταση[, κατάσταση]])
Στέλνει μια απάντηση JSON με προαιρετικές κεφαλίδες και κωδικό κατάστασης. Αυτή η μέθοδος είναι ιδανική για την οργάνωση ενός JSON API, αλλά το JSON μπορεί επίσης να σταλεί χρησιμοποιώντας res.send(obj) (το οποίο δεν είναι ιδανικό εάν θέλετε να στείλετε μόνο μια κωδικοποιημένη συμβολοσειρά JSON, καθώς το res.send(string) θα στείλει HTML)
res.json(null); res.json(( χρήστης: "tj" )); res.json("guard!", 500); res.json("Nothing found", 404);
res.redirect(url[, status])
Ανακατευθύνει στην καθορισμένη διεύθυνση URL. Ο προεπιλεγμένος κωδικός κατάστασης είναι 302.
res.redirect("/", 301); res.redirect("/account"); res.redirect("http://google.com"); res.redirect("home"); res.redirect("πίσω");
Το Express υποστηρίζει συντομεύσεις για ανακατευθύνσεις - οι προεπιλεγμένες είναι "πίσω" και "σπίτι" . Σε αυτήν την περίπτωση, το "back" ανακατευθύνει στη διεύθυνση URL που καθορίζεται στην κεφαλίδα του Referrer (ή Referer) και το "home" χρησιμοποιεί τη ρύθμιση "home" (προεπιλογή "/").
res.cookie(όνομα, val[, επιλογές])
Ορίζει την τιμή του cookie με όνομα όνομα σε val . Επιλογές: http Μόνο, ασφαλής, λήγει κ.λπ. Η επιλογή διαδρομής ορίζεται από προεπιλογή στην τιμή που έχει οριστεί στη ρύθμιση "home", συνήθως "/" .
// "Remember me" για 15 λεπτά res.cookie("rememberme", "yes", ( expires: new Date(Date.now() + 900000), httpOnly: true ));
Η ιδιότητα maxAge μπορεί να οριστεί να λήγει σε σχέση με την Date.now() σε χιλιοστά του δευτερολέπτου. Έτσι το παραπάνω παράδειγμά μας μπορεί τώρα να ξαναγραφτεί ως εξής:
res.cookie("rememberme", "yes", ( maxAge: 900000 ));
Για να αναλύσετε τα εισερχόμενα cookie, χρησιμοποιήστε το επίπεδο cookieParser, το οποίο δημιουργεί ένα αντικείμενο req.cookies:
app.use(express.cookieParser()); app.get("/", function(req, res) ( // χρήση req.cookies.rememberme ));
res.clearCookie(όνομα[, επιλογές])
Διαγράφουμε το όνομα του cookie με το όνομα , εκχωρώντας στην παράμετρο λήξης μια ημερομηνία στο μακρινό παρελθόν. Οι επιλογές είναι οι ίδιες όπως για το res.cookie() , η διαδρομή είναι επίσης προεπιλεγμένη στη ρύθμιση "home".
res.clearCookie("rememberme");
res.render(προβολή[, επιλογές[, fn]])
Αποδίδει μια προβολή με τις δεδομένες επιλογές και μια προαιρετική επανάκληση fn. Όταν δίνεται το fn, η απάντηση στον πελάτη δεν είναι αυτόματη, διαφορετικά γίνεται μια απάντηση κειμένου/html με κωδικό 200 .
Οι επιλογές που πέρασαν είναι επίσης μεταβλητές τοπικής προβολής. Για παράδειγμα, αν θέλουμε να περάσουμε τη μεταβλητή χρήστη και να απενεργοποιήσουμε τη διάταξη, το κάνουμε σε ένα αντικείμενο:
var user = (όνομα: "tj" ); res.render("index", ( διάταξη: false, user: user ));
Το αντικείμενο επιλογές χρησιμοποιείται επίσης για να περάσει επιλογές. Για παράδειγμα, εάν μεταβιβάσετε την ιδιότητα κατάστασης, όχι μόνο γίνεται διαθέσιμη στην προβολή, αλλά ορίζει επίσης τον κωδικό κατάστασης της απάντησης. Αυτό είναι επίσης χρήσιμο εάν η μηχανή προτύπων δέχεται ορισμένες επιλογές, όπως εντοπισμό σφαλμάτων ή συμπίεση . Ακολουθεί ένα παράδειγμα του τρόπου με τον οποίο μπορείτε να αποδώσετε μια σελίδα σφάλματος - η κατάσταση μεταβιβάζεται εδώ τόσο για να την εμφανίσετε όσο και για να ορίσετε τον κωδικό κατάστασης res.statusCode.
res.render("σφάλμα", ( κατάσταση: 500, μήνυμα: "Εσωτερικό σφάλμα διακομιστή" ));
res.partial(προβολή[, επιλογές])
Αποδίδει ένα τμήμα με τις δοσμένες επιλογές. Αυτή η μέθοδος είναι πάντα προσβάσιμη από την προβολή ως τοπική μεταβλητή.
- αντικείμενο - το αντικείμενο μεταβιβάστηκε στην προβολή
- όπως είναι το όνομα της μεταβλητής που θα αναπαριστά το αντικείμενο αντικειμένου ή κάθε στοιχείο της συλλογής που μεταβιβάζεται στην προβολή. Προεπιλογή είναι το όνομα της προβολής.
- ως: "κάτι" - θα προσθέσει κάτι τοπική μεταβλητή
- ως: αυτό - θα χρησιμοποιήσει το στοιχείο συλλογής ως πλαίσιο προβολής (αυτό)
- ως: καθολική - θα συγχωνεύσει τις ιδιότητες του στοιχείου συλλογής και τις μεταβλητές τοπικής προβολής
- συλλογή - μια σειρά αντικειμένων. Το όνομά του προέρχεται από το όνομα της θέας. Για παράδειγμα, το video.html θα έχει ένα αντικείμενο βίντεο μέσα.
Οι ακόλουθες κατασκευές είναι ισοδύναμες μεταξύ τους και το όνομα της συλλογής που μεταβιβάζεται στο τμήμα θα είναι πάντα "ταινία" .
partal("theatre/movie.jade", (συλλογή: ταινίες )); partal("theatre/movie.jade", ταινίες); partal("movie.jade", (συλλογή: ταινίες )); partal("movie.jade", ταινίες); μερική ("ταινία", ταινίες); // Μέσα στην προβολή: moovie.director
Για να αλλάξετε το όνομα μιας τοπικής μεταβλητής από "ταινία" σε "βίντεο", μπορείτε να χρησιμοποιήσετε την επιλογή ως:
partal("ταινία", (συλλογή: ταινίες, ως: "βίντεο" )); // Μέσα στην προβολή: video.director
Μπορούμε επίσης να κάνουμε ταινία με αυτήν την τιμή μέσα στην προβολή μας, ώστε αντί για movie.director να αναφερόμαστε σε this.director.
partal("ταινία", (συλλογή: ταινίες, όπως: αυτό )); // Μέσα στην όψη: αυτό.σκηνοθέτης
Μια εναλλακτική λύση είναι η επέκταση των ιδιοτήτων ενός στοιχείου συλλογής σε ψευδο-σφαιρικές (στην πραγματικότητα τοπικές) μεταβλητές χρησιμοποιώντας ως: καθολική , που είναι συντακτική ζάχαρη:
partal("ταινία", (συλλογή: ταινίες, ως: παγκόσμια )); // Μέσα στη θέα: σκηνοθέτης
Η ίδια λογική δεν ισχύει μόνο για συλλογές, αλλά και για ένα αντικείμενο μέσα σε μια προβολή αποσπασμάτων:
partal("ταινία", ( αντικείμενο: ταινία, ως: αυτό )); // Μέσα στην προβολή: this.director partial("ταινία", ( αντικείμενο: ταινία, ως: καθολική )); // Μέσα στην προβολή: σκηνοθέτης μερική("ταινία", ( αντικείμενο: ταινία, ως: "βίντεο" )); // Μέσα στην προβολή: video.director partal("ταινία", ( αντικείμενο: ταινία )); // σκηνοθέτης
Όταν το δεύτερο όρισμα είναι μη συλλογή (χωρίς .length), αντιμετωπίζεται ως αντικείμενο. Σε αυτήν την περίπτωση, το όνομα της τοπικής μεταβλητής για αυτό το αντικείμενο σχηματίζεται από το όνομα της προβολής.
var movie = νέα Ταινία ("Nightmare Before Christmas", "Tim Burton") μερική ("ταινία", ταινία) // => Μέσα στην προβολή: movie.director
Η εξαίρεση σε αυτόν τον κανόνα είναι όταν ένα απλό αντικείμενο ("()" ή "νέο αντικείμενο") μεταβιβάζεται, τότε θεωρείται τοπικό αντικείμενο και δεν είναι προσβάσιμο ονομαστικά σε μια προβολή τμήματος. Για παράδειγμα, στο παρακάτω παράδειγμα θα περιμένατε να υπάρχει μια τοπική μεταβλητή "ταινία" , ωστόσο, δεδομένου ότι πρόκειται για ένα απλό αντικείμενο, οι τοπικές μεταβλητές είναι ήδη "σκηνοθέτης" και "τίτλος", δηλαδή οι ιδιότητές της:
var movie = ( τίτλος: "Nightmare Before Christmas", σκηνοθέτης: "Tim Burton" ); μερική ("ταινία", ταινία)
Για τέτοιες περιπτώσεις, όταν χρειάζεται να περάσετε ένα απλό αντικείμενο, απλώς αντιστοιχίστε το σε κάποια ιδιότητα ή χρησιμοποιήστε την ιδιότητα αντικειμένου, η οποία θα κληρονομήσει το όνομα του αντικειμένου από το όνομα του αρχείου. Τα παραδείγματα που αναφέρονται παρακάτω είναι ισοδύναμα:
μερική ("ταινία", ( ντόπιοι: ( ταινία: ταινία )) μερική ("ταινία", ( ταινία: ταινία )) μερική ("ταινία", ( αντικείμενο: ταινία ))
Το ίδιο API μπορεί να χρησιμοποιηθεί από μια διαδρομή, ώστε να μπορείτε να απαντήσετε με ένα τμήμα HTML μέσω AJAX ή WebSockets, για παράδειγμα, μπορείτε να αποδώσετε μια συλλογή χρηστών απευθείας από τη διαδρομή:
app.get("/users", function(req, res) ( if (req.xhr) ( // αποστολή σε απάντηση κάθε χρήστη από τη συλλογή // μεταβιβάστηκε στην προβολή "user" res.partial("user", χρήστες) ;) else ( // απαντήστε με μια πλήρη διάταξη με μια σελίδα λίστας χρηστών // το πρότυπο της οποίας κάνει μερική("χρήστη", χρήστες) // και προσθέτει κάποιο είδος διεπαφής res.render("χρήστες", ( χρήστες: χρήστες ) ); ) ));
res.local(όνομα[, val])
Λάβετε ή ορίστε την καθορισμένη τοπική μεταβλητή. Οι τοπικές μεταβλητές σε αυτήν την περίπτωση αναφέρονται σε μεταβλητές που μεταβιβάζονται στις μεθόδους απόδοσης της προβολής, όπως η res.render() .
app.all("/movie/:id", function(req, res, next) ( Movie.get(req.params.id, function(err, movie) ( // Κάνει την ανάθεση res.locals.movie = ταινία res .local("ταινία", ταινία); )); )); app.get("/movie/:id", function(req, res) ( // η ταινία τοπικής μεταβλητής υπάρχει ήδη // αλλά μπορούμε να την προσθέσουμε εάν χρειάζεται res.render("movie", ( displayReviews: true ) ); ));
res.locals(obj)
Εκχωρήστε πολλές τοπικές μεταβλητές χρησιμοποιώντας το δεδομένο αντικείμενο obj. Το παρακάτω είναι ισοδύναμο:
res.local("foo", bar); res.local("bar", baz); res.locals(( foo: bar, bar, baz ));
Υπηρέτης
app.set(όνομα[, val])
Ορίστε τη ρύθμιση ονόματος εφαρμογής σε val ή λάβετε την τιμή της ρύθμισης ονόματος εάν λείπει το val:
app.set("views", __dirname + "/views"); app.set("προβολές"); // => ...διαδρομή...
Μπορείτε επίσης να μεταβείτε στις ρυθμίσεις μέσω των ρυθμίσεων εφαρμογών:
app.settings.views // => ...διαδρομή...
app.enable(όνομα)
Ορίζει τη ρύθμιση ονόματος σε true:
app.enable("κάποια αυθαίρετη ρύθμιση"); app.set("κάποια αυθαίρετη ρύθμιση"); // => true app.enabled("κάποια αυθαίρετη ρύθμιση"); // => αληθές
app.enabled(όνομα)
Ελέγχει εάν η ρύθμιση ονόματος είναι αληθής:
app.enabled("προβολή προσωρινής μνήμης"); // => false app.enable("προβολή προσωρινής μνήμης"); app.enabled("προβολή προσωρινής μνήμης"); // => αληθές
app.disable(όνομα)
Ορίστε τη ρύθμιση ονόματος σε false:
app.disable("κάποια ρύθμιση"); app.set("κάποια ρύθμιση"); // => false app.disabled("κάποια ρύθμιση"); // => ψευδής
app.disabled(όνομα)
Ελέγχει εάν η ρύθμιση ονόματος είναι ψευδής:
app.enable("προβολή προσωρινής μνήμης"); app.disabled("προβολή προσωρινής μνήμης"); // => false app.disable("προβολή προσωρινής μνήμης"); app.disabled("προβολή προσωρινής μνήμης"); // => αληθές
app.configure(env|συνάρτηση[, συνάρτηση])
Καθορίζει τη λειτουργία επανάκλησης για το περιβάλλον env (ή για όλα τα περιβάλλοντα):
app.configure(function() ( // τρέχει για όλα τα περιβάλλοντα )); app.configure("development", function() ( // εκτελείται μόνο για το περιβάλλον "development"));
app.redirect(όνομα, val)
Για το res.redirect() μπορούμε να ορίσουμε συντομεύσεις (στο πεδίο εφαρμογής) ως εξής:
app.redirect("google", "http://google.com");
Τώρα στη διαδρομή μπορούμε να καλέσουμε:
res.redirect("google");
Μπορείτε επίσης να κάνετε δυναμικές συντομογραφίες:
app.redirect("comments", function(req, res) ( return "/post/" + req.params.id + "/comments"; ));
Τώρα μπορείτε να κάνετε τα εξής και η ανακατεύθυνση θα κατασκευαστεί δυναμικά σύμφωνα με το πλαίσιο αιτήματος. Εάν καλέσαμε τη διαδρομή με GET /post/12, η ανακατεύθυνσή μας θα είναι /post/12/comments.
app.get("/post/:id", function(req, res) ( res.redirect("comments"); ));
Σε περίπτωση προσαρτημένης εφαρμογής, η res.redirect() θα λάβει υπόψη το σημείο προσάρτησης της εφαρμογής. Για παράδειγμα, εάν η εφαρμογή ιστολογίου είναι προσαρτημένη στο /blog , το ακόλουθο παράδειγμα θα ανακατευθύνει στο /blog/posts:
res.redirect("/posts");
app.error (συνάρτηση)
Προσθέτει μια συνάρτηση χειρισμού σφαλμάτων της οποίας η πρώτη παράμετρος δέχεται όλες τις εξαιρέσεις, όπως φαίνεται παρακάτω. Λάβετε υπόψη ότι είναι δυνατό να ορίσετε πολλούς χειριστές σφαλμάτων καλώντας αυτήν τη μέθοδο πολλές φορές, ωστόσο η μέθοδος πρέπει να καλέσει την next() εάν δεν θέλει να χειριστεί την ίδια την εξαίρεση:
app.error(function(err, req, res, next) ( res.send(err.message, 500); ));
app.helpers(obj)
Καταχωρεί βοηθούς στατικής προβολής.
app.helpers(( name: function(first, last) ( return first + ", " + last ), firstName: "tj", lastName: "holowaychuk" ));
Η προβολή μας μπορεί τώρα να χρησιμοποιήσει τις μεταβλητές firstName και lastName και τη συνάρτηση name().
<%= name(firstName, lastName) %>
Το Express παρέχει επίσης πολλές τοπικές μεταβλητές από προεπιλογή:
- ρυθμίσεις - αντικείμενο ρυθμίσεων εφαρμογής
- layout(path) καθορίζει τη διάταξη απευθείας από το εσωτερικό της προβολής
Αυτή η μέθοδος ονομάζεται app.locals() .
app.dynamicHelpers(obj) (#app.dynamic-helpers)
Καταχωρεί βοηθούς δυναμικής προβολής. Οι βοηθοί δυναμικής προβολής είναι απλώς συναρτήσεις που παίρνουν res , req και εκτελούνται στο πλαίσιο της παρουσίας του διακομιστή πριν από την απόδοση οποιασδήποτε προβολής. Η επιστρεφόμενη τιμή μιας τέτοιας συνάρτησης γίνεται μια τοπική μεταβλητή με την οποία συσχετίζεται η συνάρτηση.
app.dynamicHelpers(( session: function(req, res) ( return req.session; ) ));
Τώρα όλες οι προβολές μας θα έχουν πρόσβαση στη συνεδρία - τα δεδομένα της περιόδου σύνδεσης θα είναι διαθέσιμα με τον τρόπο session.name, κ.λπ.:
<%= session.name %>
app.lookup
Επιστρέφει τους χειριστές διαδρομών που σχετίζονται με τη δεδομένη διαδρομή.
Ας πούμε ότι υπάρχουν αυτές οι διαδρομές:
Μπορείτε να χρησιμοποιήσετε τη λειτουργία αναζήτησης για να ελέγξετε ποιες διαδρομές έχουν καθοριστεί. Αυτό μπορεί να είναι χρήσιμο για πλαίσια υψηλότερου επιπέδου που έχουν δημιουργηθεί στο 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("/hey"); // =>
Το ψευδώνυμο για app.lookup.HTTP_METHOD() είναι απλώς app.HTTP_METHOD() - χωρίς το όρισμα επανάκλησης. Αυτή είναι η μείωση. Για παράδειγμα, το παρακάτω είναι ισοδύναμο:
app.lookup.get("/user"); app.get("/user");
Κάθε συνάρτηση που επιστρέφεται συμπληρώνεται με χρήσιμες ιδιότητες:
var fn = app.get("/user/:id/:op?"); fn.regexp // => /^\/user\/(?:([^\/]+?))(?:\/([^\/]+?))?\/?$/i fn .keys // => ["id", "op"] fn.path // => "/user/:id/:op?" fn.method // => "GET"
app.match
Επιστρέφει μια σειρά από συναρτήσεις επανάκλησης που ενεργοποιούνται στη δεδομένη διεύθυνση URL, η οποία μπορεί να περιέχει μια συμβολοσειρά ερωτήματος κ.λπ. Αυτό μπορεί να είναι χρήσιμο για να κατανοήσετε ποιες διαδρομές έχουν τη δυνατότητα να ανταποκρίνονται.
Ας πούμε ότι έχουμε τις εξής διαδρομές:
app.get("/user/:id", function() ()); app.put("/user/:id", function() ()); app.get("/user/:id/:op?", function() ());
Η κλήση αντιστοίχισης στο GET θα επιστρέψει δύο συναρτήσεις επειδή το :op στην τελευταία διαδρομή είναι μια προαιρετική παράμετρος.
app.match.get("/user/1"); // =>
Και η επόμενη κλήση θα επιστρέψει μόνο μία επανάκληση για /user/:id/:op? .
app.match.get("/user/23/edit"); // =>
Μπορούμε επίσης να χρησιμοποιήσουμε το all() εάν η μέθοδος HTTP δεν είναι σημαντική για εμάς
app.match.all("/user/20"); // =>
Κάθε λειτουργία είναι εξοπλισμένη με τις ακόλουθες ιδιότητες:
var fn = app.match.get("/user/23/edit"); fn.keys // => ["id", "op"] fn.params // => ( id: "23", op: "edit" ) fn.method // => "GET"
app.mounted(fn)
Εκχωρήστε μια επανάκληση στο fn που καλείται όταν αυτός ο Διακομιστής μεταβιβαστεί στον Server.use() .
var app = express.createServer(), blog = express.createServer(); blog.mounted(function(parent) ( //parent is app // this is blog )); app.use(blog);
app.register (ext, εξαγωγές)
Συσχετίζει τις καθορισμένες ιδιότητες εξαγωγής (εξαγωγές) της μηχανής προτύπου με την επέκταση ext του αρχείου προτύπου.
app.register(".html", require("jade"));
Αυτό μπορεί επίσης να είναι χρήσιμο στην περίπτωση βιβλιοθηκών των οποίων το όνομα δεν ταιριάζει ακριβώς με την επέκταση αρχείου προτύπου. Ζωντανό παράδειγμα - Haml.js, το οποίο είναι εγκατεστημένο npm-om ως "hamljs" και μπορούμε να το καταχωρήσουμε με πρότυπα ".haml" αντί ".hamljs" όπως θα ήταν η προεπιλογή:
app.register(".haml", require("haml-js"));
Επιπλέον, το app.register είναι πολύ χρήσιμο στην περίπτωση κινητήρων προτύπων των οποίων το API δεν συμμορφώνεται με τις προδιαγραφές Express. Στο παρακάτω παράδειγμα συσχετίζουμε την επέκταση .md με το renderer χαμήλωση τιμής-αρχεία. Θα αποδώσουμε σε HTML μόνο την πρώτη φορά - για καλύτερη απόδοση - και θα υποστηρίξουμε την αντικατάσταση μεταβλητής της φόρμας "(όνομα)".
app.register(".md", ( compile: function(str, options) ( var html = md.toHTML(str); return function( locals) ( return html.replace(/\(([^)]+) \)/g, συνάρτηση(_, όνομα) (επιστροφή τοπικών; )); ) ));
app.listen()
Συνδέουμε την υποδοχή διακομιστή εφαρμογής στη διεύθυνση host:port. Η προεπιλεγμένη θύρα είναι 3000, ο κεντρικός υπολογιστής είναι INADDR_ANY.
app.listen(); app.listen(3000); app.listen(3000, "n.n.n.n");
Το όρισμα θύρας μπορεί επίσης να είναι μια συμβολοσειρά που αντιπροσωπεύει τη διαδρομή προς υποδοχή τομέα unix:
app.listen("/tmp/express.sock");
Τώρα ας προσπαθήσουμε:
$ telnet /tmp/express.sock GET / HTTP/1.1 HTTP/1.1 200 OK Τύπος περιεχομένου: κείμενο/απλό Περιεχόμενο-Μήκος: 11 Hello World
Συμμετέχοντες στο έργο
Οι κύριοι συντελεστές του έργου ήταν οι εξής:
- TJ Holowaychuk (visionmedia)
- Ciaran Jessup (ciaranj)
- Aaron Heckmann (aheckmann)
- Guillermo Rauch (guille)
Ενότητες τρίτων
Οι παρακάτω ενότητες λειτουργούν ή είναι κατασκευασμένες πάνω από το Express:
- παρέχει δρομολόγηση πόρων
- Express-messages που αποδίδουν αναδυόμενες ειδοποιήσεις
- υποστήριξη express-configure για ασύγχρονη διαμόρφωση (φόρτωση δεδομένων από το Redis, κ.λπ.)
- express-namespace - χώροι ονομάτων σε διαδρομές
- Το express-expose απλώς δημοσιεύει τον κώδικα JS στην πλευρά του πελάτη της εφαρμογής
- επεκτάσεις express-params - app.param().
- express-mongoose - πρόσθετο για την εύκολη απόδοση των αποτελεσμάτων των ερωτημάτων Mongoose (ORM για MongoDB)
Βασικά στοιχεία του Node JS & Express (III).
Ας καταλάβουμε τι είναι το npm και σε τι χρειάζεται. Εγκαταστήστε τη μηχανή προτύπων Express και EJS. Κάνουμε όλες τις προπαρασκευαστικές εργασίες και αρχίζουμε να δημιουργούμε τον δικό μας ιστότοπο στο NodeJS.Τώρα με παραμέτρους που θα αλλάζουν συνεχώς.
Εάν πρέπει να δημιουργήσουμε μια αναφορά σε μια συγκεκριμένη τιμή, μετά το /mews/value . Θα αλλάξει. Για παράδειγμα: 23, μέρος ή οποιαδήποτε άλλη τιμή.App.get("/news/:id", function(req, res)( res.send("Το αναγνωριστικό είναι - " + req.params.id); ));
Ανάλογα με αυτή την παράμετρο, μπορούμε να πάρουμε δεδομένα από τη βάση δεδομένων (βάση δεδομένων) και να εμφανίσουμε ένα συγκεκριμένο άρθρο.
Χρειαζόμαστε ένα συγκεκριμένο αρχείο html όπου θα μεταφέρουμε τα δεδομένα του αναγνωριστικού μας και, ανάλογα με αυτά τα δεδομένα, θα εμφανίζουμε αυτήν ή την άλλη πληροφορία.
Χρειαζόμαστε λίγα κινητήρας προτύπου.
Χάρη στην Express, μπορούμε να χρησιμοποιήσουμε πολλαπλούς κινητήρες προτύπων.
Δεδομένου ότι το EJS είναι ένα προαιρετικό πακέτο, πρέπει να το εγκαταστήσουμε.
πατήστε Enter
Μετά από αυτό θα εγκατασταθεί στο έργο μας.
Σας επιτρέπει να μεταβιβάζετε δεδομένα σε διάφορα πρότυπα και αυτά τα πρότυπα θα έχουν επέκταση .ejs.
Σε αυτά τα πρότυπα θα μπορούμε να εμφανίζουμε τον κώδικα html μας μαζί με τον κώδικα js που έχει εισαχθεί σε αυτόν (μεταβλητές, βρόχους εξόδου και πολλά άλλα).
Θα υπάρχει ένα πρότυπο σελίδας που θα αλλάζει ανάλογα με τα δεδομένα που μεταφέρονται σε αυτό.
Το πρώτο πράγμα που πρέπει να κάνουμε είναι να καθορίσουμε ποια μηχανή προβολής θα χρησιμοποιήσουμε.
Η μηχανή προβολής είναι ουσιαστικά μια μηχανή προτύπων.
Δεδομένου ότι ο αριθμός τους είναι τεράστιος και επιλέξαμε EJS, πρέπει να το αναφέρουμε στο αρχείο index.js.
Αμέσως μετά την προετοιμασία της μεταβλητής εφαρμογής.
App.set("view-engine", "ejs");
Όλα τα αρχεία που θα εμφανίσουμε θα αναζητηθούν στο φάκελο προβολές από προεπιλογή.
Στο ίδιο επίπεδο όπου index.js θα δημιουργήσουμε έναν φάκελο προβολών.
Σε αυτό θα δημιουργήσουμε ένα νέο αρχείο news.ejs. Αυτό θα είναι ένα είδος προτύπου που θα συμπληρώσουμε.
Μπορούμε να βάλουμε τον πιο συνηθισμένο κώδικα html σε αυτά τα πρότυπα.
Σελίδα ειδήσεων.
Για να γίνει αυτό, δεν χρειάζεται να χρησιμοποιήσω τη μέθοδο .send ή .sendFile, αλλά θα χρειαστώ τη μέθοδο render().
Η μέθοδος render() παίρνει το επιθυμητό αρχείο (πρότυπο) στο φάκελο προβολών και μπορεί να το εμφανίσει στο πρόγραμμα περιήγησης. Επιπλέον, μπορεί να περάσει ορισμένες παραμέτρους σε αυτό το πρότυπο.
Η επέκταση ενδέχεται να μην καθορίζεται στη μέθοδο render(). Στη συνέχεια, μπορείτε να περάσετε ορισμένες παραμέτρους στο ίδιο το πρότυπο. Επομένως, περνάμε το αντικείμενο ως δεύτερη παράμετρο. Μπορεί να περιέχει μεγάλο αριθμό ιδιοτήτων και αξιών.
Ας πούμε ότι αποφασίσαμε να περάσουμε μια συγκεκριμένη παράμετρο newsId με την τιμή req.params.id - δηλαδή, η τιμή θα είναι το ίδιο το αναγνωριστικό που καλείται.
App.get("/news/:id", function(req, res)( render("news", (newsId: req.params.id)); ));
Έτσι, μια τιμή θα μεταβιβαστεί στο πρότυπο ειδήσεων, το οποίο θα ονομάζεται newsId με το αναγνωριστικό τιμής .
Όλα αυτά μπορούμε να τα αποδεχτούμε και να τα εμφανίσουμε στο αρχείο news.ejs.
Ας αλλάξουμε λίγο το αρχείο news.ejs. Θα εμφανίσουμε το αναγνωριστικό στον τίτλο της σελίδας.
Μπορείτε να βρείτε τα πάντα στην τεκμηρίωση για τη μηχανή προτύπων EJS (σύνδεσμος παραπάνω).
Σελίδα ειδήσεων με ταυτότητα =<%= newsId %>
Αρχείο /views/news.ejs
Σελίδα ειδήσεων με ταυτότητα =<%= 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. Lorem ipsum dolor sit amet, consectetur adipisicing. Maiores enim vitae dolore nemo quas aliquam quia corrupti rerum ipsam ad nesciunt, architecto, pariatur officiis. Maxime iste ullam quibusdam, nobis voluptas!
αρχείο index.js
Let express = require("express"); let app = express(); app.set("προβολή κινητήρα", "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);
Μπορούμε να περάσουμε πολλές παραμέτρους. Για παράδειγμα:
App.get("/news/:id", function(req, res)( res.render("news", (newsId: req.params.id, newParam: 535 )); ));
Και στο αρχείο news.ejs θα το εμφανίσουμε στη σελίδα, για παράδειγμα ως εξής:
<%= newParam %>
Επιπλέον, μπορούμε να μεταφέρουμε τα δικά μας αντικείμενα. Για παράδειγμα, ας δημιουργήσουμε ένα αντικείμενο:
App.get("/news/:id", function(req, res)( let obj = (τίτλος:"Ειδήσεις", id: 4); res.render("news", (newsId: req.params.id, newParam: 535)); ));
Και μπορούμε επίσης να μεταφέρουμε αυτό το αντικείμενο. Αρχικά, καθορίζουμε το όνομα αυτού που θα μεταδώσουμε και μετά υποδεικνύουμε αυτό που μεταδίδουμε.
Για παράδειγμα:
App.get("/news/:id", function(req, res)( let obj = ( title:"News", id: 4); res.render("news", (newsId: req.params.id , newParam: 535, obj: obj )); ));
Τίτλος =<%= obj.title %>
ID=<%= obj.id %>
<%= newParam %>
Μεταβίβαση πίνακα στο πρότυπο.
Ας δημιουργήσουμε έναν πίνακα δεδομένων και ας τον εμφανίσουμε χρησιμοποιώντας έναν βρόχο.App.get("/news/:id", function(req, res)( let obj = ( title:"News", id: 4, παράγραφοι:["Παράγραφος", "Απλό κείμενο", "Αριθμοί: 3, 7, 24", 476]) res.render("news", (newsId: req.params.id, newParam: 535, obj: obj)); ));
Τώρα στο ίδιο το πρότυπο απλώς θα εξάγουμε αυτόν τον πίνακα σε έναν βρόχο:
-
<% obj.paragraphs.forEach(function(item) { %>
- <%= item %> <% }); %>
Στατικά αρχεία και ενδιάμεσο λογισμικό.
Αρχεία που μπορούν να συμπεριληφθούν σε άλλα αρχεία.
Τώρα έχουμε ένα πρότυπο - news.ejs, αλλά φανταστείτε. ότι είναι πολλοί από αυτούς. Ντουζίνες. Και θα χρειαστεί να κάνετε αλλαγές σε κάποιο μέρος του κώδικα που εμφανίζεται σε όλα αυτά τα αρχεία. Θα πρέπει να γίνουν πολλές αλλαγές.Για να αποφύγετε αυτό, μπορείτε να χρησιμοποιήσετε αρχεία που μπορούν να συμπεριληφθούν σε άλλα αρχεία. Για παράδειγμα. Υπάρχει ένα αρχείο με την κεφαλίδα του ιστότοπου. Και αν πρέπει να αλλάξετε κάτι, τότε αρκεί να κάνετε αλλαγές μόνο σε ένα αρχείο, αφού απλά συνδέεται με άλλα.
Στον φάκελο προβολών, δημιουργήστε έναν φάκελο που ονομάζεται blocks και σε αυτόν το αρχείο hrader.ejs.
Αρχείο hrader.ejs
- Προς κύρια
- Σχετικά με εμάς
- Νέα
Τώρα πρέπει να συμπεριλάβουμε αυτό το αρχείο σε όλα τα πρότυπα. Μεταβείτε στο αρχείο ειδήσεων και αμέσως μετά την αρχική ετικέτα σώματος γράψτε:
<% include blocks/header.ejs %>
Η διαδρομή καθορίζεται από το φάκελο προβολών, καθώς η μηχανή προτύπων ξεκινά πάντα την αναζήτηση εκεί.
Στατικά αρχεία.
Ας δημιουργήσουμε έναν νέο φάκελο σε επίπεδο index.js που ονομάζεται public. Θα περιέχει όλα τα στατικά αρχεία. Αυτά είναι αρχεία css, εικόνες, έγγραφα κ.λπ. Όλα αυτά τα αρχεία. το οποίο θα καλείται από διάφορες σελίδες του ιστότοπού μας.Σε αυτόν τον φάκελο θα δημιουργήσουμε έναν άλλο φάκελο - css και σε αυτόν θα δημιουργήσουμε ένα αρχείο style.css.
Θα μεταφέρουμε όλο τον κώδικα στυλ από το αρχείο index.ejs σε αυτό
Στα αρχεία .ejs συμπεριλαμβάνουμε τα στυλ:
Αν ελέγξετε τώρα, δεν θα γίνει τίποτα. Τα στυλ δεν θα συνδεθούν.
Για να συμπεριλάβουμε στατικά αρχεία πρέπει να χρησιμοποιήσουμε ενδιάμεσο λογισμικό:
Στο αρχείο index.js στην κορυφή, αμέσως μετά το app.set , θα πρέπει να γράψουμε:
App.use("/public",);
Και τώρα, αν χρησιμοποιήσουμε έναν σύνδεσμο κάπου που ξεκινά με /public, το NodeJS και το ίδιο το Express θα καταλάβουν τι χρησιμοποιούμε στατικά αρχείακαι όλα θα συνδεθούν σωστά.
Το δεύτερο είναι όπου τα αναζητούμε express.static("public") δηλαδή στον φάκελο /public.
Συνοψίζοντας, στον κώδικα app.use("/public", express.static("public")); παρακολουθούμε τον σύνδεσμο στον οποίο γράφουμε
Αν ήταν έτσι:
Τότε σε αυτόν τον κώδικα θα ήταν:
App.use("/assets", express.static("public"));
Σε αυτήν την περίπτωση, το δημόσιο δείχνει σε έναν φάκελο!
Εάν το αφήσετε έτσι, δεν θα υπάρξουν αλλαγές. Το αρχείο θα συνδεθεί επειδή θα παρακολουθούμε τον σύνδεσμο στοιχείων.
App.use("/assets ", express.static("public"));
Προκειμένου να αποφευχθεί η σύγχυση, συνήθως φτιάχνουν τον ομώνυμο σύνδεσμο και φάκελο. Τις περισσότερες φορές αυτό είναι δημόσιο.
Το Middleware είναι αυτό που κάνουμε πριν στείλουμε δεδομένα στη σελίδα (διακομιστής).
Σε αυτήν την περίπτωση, αυτό είναι το ενδιάμεσο λογισμικό μας.
Δημιουργία φόρμας HTML και ανάκτηση δεδομένων
Το πρώτο πράγμα που θα κάνουμε είναι να προσθέσουμε την ίδια τη φόρμα στον ιστότοπό μας.Ανοίξτε το αρχείο about.ejs και εδώ θα προσθέσουμε μια φόρμα χρησιμοποιώντας την τεχνολογία bootstrap.
Εισαγάγετε Φόρμες στο παράθυρο αναζήτησης και αντιγράψτε την πρώτη φόρμα από την κορυφή στη σελίδα που βρέθηκε.
Ας σώσουμε και ας τρέξουμε.
Αίτημα POST.
Δεδομένου ότι θα εκτελέσουμε ένα αίτημα POST, πρέπει να προσθέσουμε πολλά χαρακτηριστικά στη φόρμα.Method="post" - επειδή αίτημα POST
Και το action="" είναι το σημείο όπου πρέπει να ανακατευθύνετε τον χρήστη αφού κάνει κλικ στο "Υποβολή". Στην περίπτωσή μας είναι: