Express js greitas serveris. Node JS & Express Basics (III)
$ npm įdiegti express
arba, norėdami pasiekti greitąją komandą, įdiekite visame pasaulyje:
$ npm install -g express
Greita pradžia
Lengviausias būdas pradėti naudoti „Express“ yra paleisti greitąją komandą, kuri sugeneruos programą:
Programos kūrimas:
$ npm įdiegti -g express $ express /tmp/foo && cd /tmp/foo
Priklausomybių diegimas:
$ npm diegimas -d
Serverio paleidimas:
Serverio kūrimas
Norėdami sukurti express.HTTPServer egzempliorių, tiesiog iškvieskite metodą createServer(). Naudodami programos egzempliorių galime nurodyti maršrutus pagal HTTP metodus, šiame pavyzdyje app.get() .
var app = reikalauti("express").createServer(); app.get("/", function(req, res)( res.send("labas pasaulis"); )); app.klausytis(3000);
HTTPS serverio kūrimas
Norėdami inicijuoti express.HTTPSServer , atliekame tuos pačius veiksmus, kaip ir anksčiau, tačiau taip pat perduodame parinkčių objektą, kuriame yra raktas, sertifikatas ir kiti parametrai, aprašyti NodeJS https modulio dokumentacijoje.
var app = reikalauti("express").createServer((raktas: ... ));
Konfigūracija
Express palaiko savavališkas aplinkas, tokias kaip gamyba ir plėtra. Kūrėjai gali naudoti configure() metodą, norėdami pridėti funkcijų, reikalingų konkrečiai aplinkai. Kai configure() iškviečiama be aplinkos pavadinimo, ji suaktyvinama bet kurioje aplinkoje anksčiau nei bet kokia konfigūracija, kurioje nurodyta aplinka.
Toliau pateiktame pavyzdyje mes tiesiog naudojame parinktį dumpExceptions ir kūrimo režimu atsakome klientui pateikdami išimties pėdsaką. Abiejuose režimuose naudojame sluoksnius „metodOverride“ ir „bodyParser“. Atkreipkite dėmesį į app.router naudojimą, kuris pats leidžia prijungti maršrutus – kitu atveju jie montuojami pirmą kartą iškviečiant app.get() , app.post() ir kt.
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("gamyba", funkcija())( var oneYear = 31557600000; app.use(express.static(__dirname + "/public", ( maxAge: oneYear))); app.use(express.errorHandler() ) ; ));
Aplinkose su panašiais parametrais galite perduoti kelis aplinkos pavadinimus:
app.configure("stage", "prod", function())( // config ));
Vidiniams ir savavališkiems nustatymams Express turi metodus set(key[, val]) , enable(key) , disable(key) :
app.configure(function () ( app.set("views", __dirname + "/views"); app.set("views"); // => "/absolute/path/to/views" app.enable ("kai kuri funkcija"); .enabled("kai kuri funkcija") // => false ));
Norėdami nustatyti aplinką, galime nustatyti NODE_ENV aplinkos kintamąjį. Pavyzdžiui:
$ NODE_ENV=gamybos mazgas app.js
Tai labai svarbu, nes daugelis talpyklos mechanizmų įjungti tik gamybinėje aplinkoje.
Nustatymai
Išimta „Express“ palaiko šiuos nustatymus:
- home yra pagrindinis programos kelias, naudojamas res.redirect(), taip pat skaidriam prijungtų programų palaikymui.
- rodiniai yra šakninis rodinių katalogas. Pagal numatytuosius nustatymus current_folder/views
- peržiūros variklis – numatytasis šablono variklis rodiniams, iškviečiamiems be failo plėtinio.
- peržiūros parinktys – objektas, atspindintis visuotinio vaizdo parinktis
- rodinio talpyklą – įgalinkite rodinio talpyklą (įjungta gamybinėje aplinkoje)
- maršrutai, skirti didžiosioms ir mažosioms raidėms – įgalinti maršrutus, kuriuose skiriamos didžiosios ir mažosios raidės
- griežtas maršruto parinkimas – jei įjungta, pasvirieji brūkšniai nebepaisomi
- jsonp callback – leiskite res.send() metodui skaidriai palaikyti JSONP
Maršrutas
„Express“ naudoja HTTP metodus, kad pateiktų prasmingą, išraiškingą maršruto API. Pavyzdžiui, norime, kad ieškant /user/12 būtų rodomas vartotojo, kurio id=12, profilis. Norėdami tai padaryti, toliau apibrėžiame maršrutą. Su pavadintais laukais susietos reikšmės yra objekte res.params.
app.get("/user/:id", function(req, res)( res.send("user " + req.params.id); ));
Maršrutas yra tiesiog eilutė, kuri variklio viduje sukompiliuojama į reguliariąją išraišką. Pavyzdžiui, kai sukompiliuojamas /user/:id, rezultatas yra reguliarioji išraiška, tokia:
\/naudotojas\/([^\/]+)\/?
Taip pat galite iš karto perduoti reguliarųjį posakį. Bet kadangi grupės nėra įvardijamos įprastose išraiškose, jas galima pasiekti req.params skaičiais. Taigi pirmoji grupė patenka į req.params , antroji į req.params ir kt.
app.get(/^\/users?(?:\/(\d+)(?:\.\.(\d+))?)?)/, function(req, res)( res.send(req.params ); ));
Dabar paimkime curl ir nusiųskite užklausą aukščiau nurodytu maršrutu:
$ curl http://dev:3000/user $ curl http://dev:3000/users $ curl http://dev:3000/users/1 ["1",null] $ curl http://dev: 3000/naudotojų/1..15 ["1", "15"]
Toliau pateikiami keli maršrutų ir kelių, kurie gali juos atitikti, pavyzdžiai:
"/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
Pavyzdžiui, galime paskelbti tam tikrą JSON ir atsakyti tuo pačiu JSON naudodami sluoksnį bodyParser, kuris gali išanalizuoti JSON užklausą (taip pat ir kitas užklausas) ir įdėti atsakymą į req.body:
var express = reikalauti("express"), programa = express.createServer(); app.use(express.bodyParser()); app.post("/", function(req, res) ( res.send(req.body); )); app.klausytis(3000);
Paprastai mes naudojame „durną“ lauką (pavyzdžiui, /user/:id), kuriam nėra jokių apribojimų. Bet jei, pavyzdžiui, norime apriboti vartotojo ID iki tik skaitinių simbolių, galime naudoti /user/:id(+) . Ši konstrukcija neveiks, jei lauko reikšmėje yra ne skaitiniai simboliai.
Valdymo perkėlimas į kitą maršrutą
Iškviesdami trečiąjį argumentą next() , galite perduoti valdymą kitam maršrutui. Jei atitikmuo nerandamas, valdymas grąžinamas Connect ir sluoksniai toliau iškviečiami tokia tvarka, kokia jie buvo įjungti naudojant use() . Taip pat veikia keli maršrutai, turintys tą patį kelią. Jie tiesiog kviečiami po vieną, kol vienas iš jų atsako, o ne skambina next() .
app.get("/users/:id?", function(req, res, next) ( var id = req.params.id; if (id) ( // padaryti ką nors ) else ( next(); ) )) ; app.get("/users", function(req, res) ( // padaryti ką nors kita ));
App.all() metodas yra naudingas, jei norite atlikti tą pačią logiką visiems HTTP metodams. Žemiau mes naudojame šį metodą, norėdami gauti vartotoją iš duomenų bazės ir priskirti jį req.user.
var express = reikalauti("express"), programa = express.createServer(); var vartotojai = [( vardas: "tj" )]; app.all("/user/:id/:op?", function(req, res, next) ( req.user = vartotojai; if (req.user) ( next(); ) else ( next(new Error( "nepavyko rasti vartotojo" + req.params.id)); app.get("/user/:id", function(req, res) ( res.send("peržiūra " + req.user.name); )); app.get("/user/:id/edit", function(req, res) ( res.send("redagavimas " + req.user.name); )); app.put("/user/:id", function(req, res) ( res.send("atnaujinama " + req.user.name); )); app.get("*", function(req, res) ( res.send("kas???", 404); )); app.klausytis(3000);
Tarpsluoksniai
Connect framework sluoksniai gali būti perduoti express.createServer() taip pat, lyg būtų naudojamas įprastas Connect serveris. Pavyzdžiui:
var express = reikalauti("išreikšti"); var app = express.createServer(express.logger(), express.bodyParser());
Taip pat galite naudoti use () . Tai leidžia patogiau pridėti sluoksnius configure () blokuose, o tai yra progresyvesnė.
app.use(express.logger(( formatas: ":method:url" )));
Paprastai su „Connect“ sluoksniais „Connect“ galime sujungti taip:
var connect = reikalauti("prisijungti"); app.use(connect.logger()); app.use(connect.bodyParser());
Tai nėra visiškai patogu, todėl „Express“ pakartotinai eksportuoja „Connect“ sluoksnius:
app.use(express.logger()); app.use(express.bodyParser());
Svarbi sluoksnių tvarka. Taigi, kai Connect gauna užklausą, vykdomas pirmasis sluoksnis, pridėtas per createServer() arba use(). Jis iškviečiamas naudojant tris parametrus: užklausa , atsakymas ir atgalinio skambinimo funkcija, paprastai vadinama next . kai iškviečiamas next(), valdymas perduodamas antrajam sluoksniui ir pan. Į tai svarbu atsižvelgti, nes daugelis sluoksnių priklauso vienas nuo kito. Pavyzdžiui, methodOverride() iškviečia req.body.method, kad perkrautų HTTP metodą, o bodyParser() analizuoja užklausos turinį, kad užpildytų req.body . Kitas pavyzdys yra slapukų analizavimas ir seanso palaikymas – pirmiausia reikia iškviesti use() naudojant cookieParser() , tada – session() .
Daugelyje „Express“ programų gali būti eilutė app.use(app.router). Tai gali atrodyti keista, bet tai tiesiog norint aiškiai nurodyti sluoksnį, kuriame yra visi mūsų sukurti maršrutai. Šis sluoksnis gali būti įtrauktas bet kokia tvarka, nors pagal numatytuosius nustatymus jis įtraukiamas pabaigoje. Keisdami jo padėtį, galite kontroliuoti jo vykdymo tvarką. Pavyzdžiui, mums reikia klaidų tvarkyklės, kuri įsijungs po visų kitų sluoksnių ir parodys visas išimtis, perduotas naudojant next() . Arba gali prireikti sumažinti statinius failus aptarnaujančio sluoksnio vykdymo tvarką, kad kiti maršrutai galėtų perimti tokių failų užklausas ir, pavyzdžiui, suskaičiuoti atsisiuntimų skaičių ir pan. Štai kaip tai gali atrodyti:
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(...));
Pirmiausia pridedame logger() – jis apims req.end() metodą, kad pateiktų atsakymo dažnio duomenis. Tada išanalizuojame užklausos turinį (jei toks yra), tada slapukus, tada sesiją, kad req.session jau būtų apibrėžta, kai pasiekiame app.router maršrutus. Jei, pavyzdžiui, GET užklausa /javascripts/jquery.js yra apdorojama maršrutais ir mes neiškviečiame next() , tada static() sluoksnis niekada negaus tos užklausos. Tačiau jei apibrėžsime maršrutą, kaip parodyta žemiau, bus galima įrašyti statistiką, atmesti atsisiuntimus, apmokestinti atsisiuntimus ir pan.
var atsisiuntimai = (); app.use(app.router); app.use(express.static(__dirname + "/public")); app.get("/*", function(req, res, next) ( var failas = req.params; atsisiuntimai = atsisiuntimai || 0; atsisiuntimai++; next(); ));
Sluoksnių maršrutai
Maršrutai gali naudoti maršruto parinkimo sluoksnius, metodui perduodami papildomus atgalinius skambučius (arba masyvus). Tai naudinga, jei prieš naudojant maršrutą reikia apriboti prieigą arba įkelti duomenis ir pan.
Paprastai asinchroninis duomenų gavimas gali atrodyti panašiai, kaip parodyta žemiau (čia paimame parametrą:id ir įkeliame vartotojo duomenis).
app.get("/user/:id", function(req, res, next) ( loadUser(req.params.id, function(err, user) ( if (err) return next(err); res.send( "Peržiūrimas vartotojas" + vartotojo.vardas);
Norėdami laikytis DRY principo ir pagerinti kodo skaitomumą, tokią logiką galite organizuoti naudodami sluoksnius. Kaip matote, abstrahuodami logiką naudodami sluoksnius galite pasiekti pakartotinį sluoksnių panaudojimą ir padaryti maršruto kodą gražesnį.
function loadUser(req, res, next) ( // čia įkeliame vartotoją iš duomenų bazės var user = users; if (user) ( req.user = user; next(); ) else ( next(new Error("Nepavyko įkelti vartotoją " + req.params.id)); ) ) app.get("/user/:id", loadUser, function(req, res) ( res.send("Peržiūrimas vartotojas " + req.user.name ) ; ));
Galima pridėti kelis maršruto parinkimo sluoksnius ir jie bus vykdomi nuosekliai, kad būtų sukurta skirtinga logika, pavyzdžiui, apribojama prieiga prie vartotojo abonemento. Toliau pateiktame pavyzdyje tik įgaliotas naudotojas gali redaguoti savo paskyrą.
funkcija andRestrictToSelf(req, res, next) ( req.authenticatedUser.id == req.user.id ? next() : next(new Error("Unauthorized")); ) app.get("/user/:id/ redaguoti", loadUser irRestrictToSelf, function(req, res) ( res.send("Redaguoti naudotoją " + req.user.name); ));
Suprasdami, kad sluoksniai yra tik funkcijos, galite parašyti funkciją, kuri grąžina sluoksnį (kad būtų dar išraiškingesnis ir lankstesnis sprendimas), kaip parodyta toliau.
function andRestrictTo(role) ( return function(req, res, next) ( req.authenticatedUser.role == role ? next() : next(new Error("Unauthorized")); ) ) app.del("/user/ :id", loadUser irRestrictTo("admin"), function(req, res) ( res.send("Ištrintas vartotojas " + req.user.name); ));
Dažnai naudojami sluoksnių „krūvos“ gali būti perduodami kaip savavališko gylio ir medžio struktūros masyvai (jie bus taikomi rekursyviai):
var a = , b = , visi = ; app.get("/foo", a, function() ()); app.get("/bar", a, function() ()); app.get("/", a, tarpinė programinė įranga3, tarpinė programinė įranga4, funkcija() ()); app.get("/", a, b, function() ()); app.get("/", viskas, funkcija() ());
Visą pavyzdį galima peržiūrėti saugykloje.
Kartais reikia praleisti likusius maršruto sluoksnius, bet tęsti kitus maršrutus. Norėdami tai padaryti, iškvieskite next() su maršruto argumentu: next("route") . Jei nebeliko vykdytinų maršrutų, „Express“ atsakys klaidos pranešimu 404 Not Found.
HTTP metodai
Jau keletą kartų naudojome app.get(), bet Express pateikia ir kitus HTTP metodus – app.post() , app.del() ir kt.
Dažniausias POST naudojimo atvejis yra pateikiant formą. Toliau pateiktame pavyzdyje mes tiesiog sukuriame HTML formą. Tada valdymas bus perkeltas į maršrutą, kurį nustatysime kitame pavyzdyje.
Pagal numatytuosius nustatymus „Express“ nežino, ką daryti su užklausos turiniu, todėl turime pridėti „bodyParser() sluoksnį, kuris išanalizuoja užklausos turinį, užkoduotą Application/x-www-form-urlencoded arba application/json, ir įdės analizės rezultatai req .body . Norėdami tai padaryti, turime pasakyti use (), kaip nurodyta toliau:
app.use(express.bodyParser());
Dabar toliau nurodytu maršrutu bus galima pasiekti objektą req.body.user, kuris turės vardo ir el. pašto ypatybes:
app.post("/", function(req, res) ( console.log(req.body.user); res.redirect("atgal"); ));
Jei formoje naudojami tokie metodai kaip PUT, galite naudoti paslėptą įvestį, vadinamą _method, kuri leidžia pakeisti HTTP metodą. Norėdami tai pasiekti, pirmiausia turime įjungti metodoOverride() sluoksnį, kuris bus dedamas po bodyParser(), kuris leis naudoti req.body, kuriame yra pateiktos formos laukai.
app.use(express.bodyParser()); app.use(express.methodOverride());
Šie sluoksniai nėra įjungti pagal numatytuosius nustatymus, nes „Express“ nebūtinai turi visas funkcijas iš karto. Atsižvelgiant į programos poreikius, jums gali nereikėti jų naudoti. Tada PUT ir DELETE metodai vis tiek bus prieinami, bet tiesiogiai. Tuo pačiu metu methodOverride yra puikus sprendimas HTML formoms. Toliau pateikiamas PUT metodo naudojimo pavyzdys:
app.put("/", function() ( console.log(req.body.user); res.redirect("atgal"); ));Apdorojant įvyko klaida
„Express“ turi metodą app.error(), kuris priima bet kokias maršrutų nustatytas išimtis arba perduodamas kaip next(err) . Toliau pateikiamas pavyzdys, kaip pateikti kelis puslapius naudojant naminę „NotFound“ išimtį:
function NotFound(msg) ( this.name = "Nerasta"; Error.call(this, msg); Error.captureStackTrace(this, arguments.callee); ) NotFound.prototype.__proto__ = Error.prototype; app.get("/404", function(req, res) ( mesti naują NotFound; )); app.get("/500", function(req, res) ( mesti naują Error("klaviatūros katė!"); ));
Galite iškviesti app.error() kelis kartus, kaip parodyta toliau. Čia patikriname, ar nėra NotFound egzemplioriaus, ir parodome 404 puslapį arba perduodame valdymą kitai klaidų tvarkyklei.
Atkreipkite dėmesį, kad šiuos tvarkykles galima apibrėžti bet kur, nes jie vis tiek bus žemiau maršruto tvarkytuvų klausime () . Tai leidžia jas apibrėžti configure() blokuose, todėl išimtys gali būti tvarkomos skirtingai, atsižvelgiant į esamą aplinką.
app.error(function(err, req, res, next) ( if (err instanceof NotFound) ( res.render("404.jade"); ) else ( next(err); ) ));
Paprastumo sumetimais darome prielaidą, kad visų klaidų kodas yra 500, tačiau galite tai pakeisti kaip norite. Pavyzdžiui, kai Node atlieka failų sistemos operacijas, galime gauti klaidos objektą su lauku error.code = ENOENT, o tai reiškia „failas arba katalogas nerastas“, galime tai naudoti klaidų tvarkyklėje ir parodyti atitinkamą puslapį.
app.error(function(err, req, res) ( res.render("500.jade", ( klaida: err )); ));
Programos taip pat gali naudoti „Connect errorHander“ sluoksnį, kad tvarkytų išimtis. Pavyzdžiui, jei jums reikia rodyti išimtis stderr kūrimo aplinkoje, galite tai padaryti:
app.use(express.errorHandler(( dumpExceptions: true )));
Be to, kūrimo metu mums gali prireikti puikių HTML puslapių, kuriuose rodomos išmestos arba išmestos išimtys. Tokiu atveju turite nustatyti „showStack“ į „true“:
app.use(express.errorHandler(( showStack: true, dumpExceptions: true )));
ErrorHandler sluoksnis taip pat reaguoja JSON, jei klientas perduoda Accept: application/json antraštę, kuri yra naudinga kuriant AJAX programas.
Išankstinis maršruto parametrų apdorojimas
Išankstinis maršruto parametrų apdorojimas gali žymiai pagerinti programos skaitomumą, nes aiškiai įkeliami duomenys ir prašoma URL patvirtinimo. Pavyzdžiui, jei nuolat nuskaitote tam tikrų užklausų duomenis (pvz., įkeliate vartotojo duomenis /user/:id), galite padaryti kažką panašaus:
app.get("/user/:userId", function(req, res, next) ( User.get(req.params.userId, function(err, user)) ( if (err) return next(err); res. send("vartotojas " + vartotojo.vardas ));
Turėdami išankstines sąlygas, prie savo užklausos parametrų galime pridėti atgalinio ryšio funkcijas, kurios atliktų patvirtinimą, apribotų prieigą ar net įkeltų duomenis iš duomenų bazės. Toliau pateiktame pavyzdyje iškviečiame app.param() su parametro, prie kurio norime pridėti atgalinį skambutį, pavadinimu. Kaip matote, gauname id argumentą, kuriame yra lauko pavadinimas. Tokiu būdu įkeliame vartotojo objektą ir atliekame įprastą klaidų apdorojimą bei paprastą next() iškvietimą, kad valdymas būtų perduotas kitai išankstinei sąlygai arba maršruto tvarkytojui.
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("nepavyko rasti vartotojo"));
Aukščiau pateikti veiksmai, kaip jau minėta, žymiai pagerina kodo skaitomumą ir leidžia lengvai naudoti tą pačią logiką įvairiose programos vietose:
app.get("/user/:userId", function(req, res) ( res.send("user " + req.user.name); ));
Vaizdų atvaizdavimas
Žiūrėkite failų pavadinimus pagal schemą (pavadinimą). (variklis), kur (variklis) yra šablono variklio modulio, kurį reikia prijungti, pavadinimas. Pavyzdžiui, rodinys layout.ejs nurodo rodinio sistemai atlikti reikalavimą ("ejs") . Norint integruoti su Express, įkeliamas modulis turi eksportuoti metodą, exports.compile(str, options) ir grąžinti funkciją. Norėdami pakeisti šį elgesį, galite naudoti metodą app.register() – jis leidžia susieti failų plėtinius su konkrečiais varikliais. Pavyzdžiui, galite padaryti, kad variklis pateiktų foo.html ejs.
Žemiau pateikiamas naudojimo pavyzdys Jade norėdami pateikti index.html . Ir kadangi mes nenaudojame layout:false , rodinio index.jade pateiktas turinys bus perduotas kaip vietinis kūno kintamasis į layout.jade rodinį.
app.get("/", function(req, res) ( res.render("index.jade", ( pavadinimas: "Mano svetainė" )); ));
Nustatę peržiūros modulį, galite nurodyti numatytąjį šablono variklį. Taigi, pavyzdžiui, naudodami Jade galite tai padaryti:
app.set("peržiūros variklis", "jade");
kuri leis mums pateikti taip:
res.render("indeksas");
Bet ne taip:
res.render("index.jade");
Kai šablono variklis įdiegtas per peržiūros variklį, failų plėtinių nereikia. Tačiau vis tiek galime vienu metu naudoti kelis šablonų variklius:
res.render("kitas puslapis.ejs");
„Express“ taip pat turi rodinio parinkčių nustatymą, kuris bus taikomas kiekvieną kartą, kai vaizdas pateikiamas. Pavyzdžiui, jei ne taip dažnai naudojate maketus, galite tai parašyti taip:
app.set("peržiūros parinktys", ( išdėstymas: false ));
Kuris gali būti perkrautas, jei reikia, iškviečiant res.render() :
res.render("myview.ejs", ( išdėstymas: tiesa ));
Kai reikia kitokio išdėstymo, taip pat galite nurodyti kelią. Pavyzdžiui, jei peržiūros variklis nustatytas į jade, o išdėstymo failas vadinamas ./views/mylayout.jade , galime tiesiog perduoti:
res.render("puslapis", ( išdėstymas: "mano išdėstymas" ));
Kitu atveju galite perduoti failo plėtinį:
res.render("puslapis", ( išdėstymas: "mylayout.jade" ));
Keliai taip pat gali būti absoliutūs:
res.render("puslapis", ( išdėstymas: __dirname + "/../../mylayout.jade" ));
Geras pavyzdys yra nestandartinių variklio atidarymo ir uždarymo žymų nurodymas ejs:
app.set("peržiūros parinktys", ( atidaryti: "((", uždaryti: "))" ));
Peržiūrėti fragmentus
„Express view“ sistemoje yra įmontuotas fragmentų ir kolekcijų palaikymas, savotiškas mini vaizdas. Pavyzdžiui, užuot peržiūrėję rodinį, kad būtų rodomas komentarų sąrašas, galite tiesiog naudoti kolekcijos fragmentą:
dalinis("komentaras", (rinkinys: komentarai));
Jei nereikia kitų parinkčių ar vietinių kintamųjų, galite praleisti objektą ir tiesiog perduoti duomenų masyvą. Žemiau pateiktas pavyzdys yra lygiavertis ankstesniam:
dalinis("komentaras", komentarai);
Naudodami kolekcijas turime keletą „stebuklingų“ vietinių kintamųjų:
- firstInCollection – tiesa, jei tai pirmasis objektas
- indexInCollection – kolekcijoje esančio objekto indeksas
- lastInCollection – tiesa, jei tai paskutinis objektas
- collectionLength – kolekcijos ilgis
Pirmenybė teikiama perduotiems arba sugeneruotiems vietiniams kintamiesiems, tačiau pirminiam rodiniui perduoti vietiniai kintamieji taip pat pasiekiami antriniam rodiniui. Pavyzdžiui, jei pateikiame rodinį naudodami partial ("tinklaraštis/post", įrašas) ir jis sukuria vietinio kintamojo įrašą , o rodinys, kuris iškvietė šią funkciją, turėjo vietinį kintamąjį vartotojas , vartotojas taip pat bus matomas tinklaraštyje /post vaizdas.
Daugiau dokumentacijos žr. res.partial().
Pastaba: rinkinius naudokite atsargiai, nes 100 elementų masyvo atvaizdavimas reiškia 100 rodinių. Paprastoms kolekcijoms geriau peržiūrėti rodinį, o ne naudoti kolekcijas. Taip apkrova bus mažesnė.
Ieškoti rodinių
Rodinių ieškoma pagal pirminį rodinį. Pavyzdžiui, jei turime rodinį views/user/list.jade ir jame iškviečiame partial("edit") , sistema bandys įkelti rodinį views/user/edit.jade , o partial(../ pranešimai"), atsisiųsite view/messages.jade
Peržiūrų sistema taip pat leidžia kurti indekso failus. Pavyzdžiui, galime iškviesti res.render("users") ir tai gali įkelti tiek views/users.jade, tiek views/users/index.jade .
Taip pat galite naudoti rodyklės failus iš to paties katalogo rodinio. Taigi iškvietus partial("users"), galima pasiekti rodinį ../users/index, o ne skambinti partial("index") .
Šablonų varikliai
Toliau pateikiami keli šablonų varikliai, dažniausiai naudojami su Express:
- E.J.S.- Integruotas JavaScript
- CoffeeKup- šablono pagrindu CoffeeScript
- jQuery šablonai už Node
Sesijos palaikymas
Seanso palaikymą galima įjungti naudojant „Connect“ seanso sluoksnį. Taip pat tam mums reikia viršutinio cookieParser sluoksnio, kuris išnagrinės slapukus ir įdės juos į req.cookies.
app.use(express.cookieParser()); app.use(express.session(( paslaptis: "klaviatūros katė" )));
Pagal numatytuosius nustatymus seanso sluoksnis naudoja „Connect“ atmintyje esančią saugyklą, tačiau yra daug kitų sprendimų. Pavyzdžiui prisijungti-redis palaiko seanso saugojimą Redis. Štai kaip juo naudotis:
var RedisStore = reikalauti("connect-redis")(express); app.use(express.cookieParser()); app.use(express.session(( paslaptis: "klaviatūros katė", parduotuvė: new RedisStore )));
Dabar „req.session“ ir „req.sessionStore“ ypatybės bus pasiekiamos visuose maršrutuose ir vėlesniuose sluoksniuose. Req.session ypatybės automatiškai išsaugomos atsakius. Štai kaip sutvarkyti krepšelį:
var RedisStore = reikalauti("connect-redis")(express); app.use(express.bodyParser()); app.use(express.cookieParser()); app.use(express.session(( paslaptis: "klaviatūros katė", parduotuvė: new RedisStore ))); app.post("/add-to-cart", function(req, res) ( // tarkime, kad perdavėme kelis objektus iš formos // naudokite bodyParser() šiam var elementams = req.body.items; req. sesijos elementai = elementai res.redirect("atgal" )); app.get("/add-to-cart", function(req, res) ( // Kai nukreipiame į GET /add-to-cart // galime patikrinti req.session.items && req.session.items . ilgis // norėdami atspausdinti mūsų pranešimą if (req.session.items && req.session.items.length) ( req.flash("info", "Jūsų krepšelyje yra %s prekės", req.session.items. ilgis ); res.render("pirkinių krepšelis");
Objektas req.session taip pat turi Session.touch() , Session.destroy() , Session.regenerate() metodus, skirtus manipuliuoti seansais. Norėdami gauti išsamesnės informacijos, žr. Connect Session dokumentaciją.
Migracijos vadovas
Kūrėjai, dirbę su Express 1.x, gali peržiūrėti perkėlimo vadovą, kad jų programos veiktų su Express 2.x, Connect 1.x ir Node 0.4.x.
Prašymas
req.header(raktas[, numatytoji vertė])
Gaukite rakto užklausos antraštę (neskiriamos didžiosios ir mažosios raidės) su pasirenkama numatytąją Numatytąją vertę:
req.header("Host"); req.header("host"); req.header("Priimti", "*/*");
Referrer ir Referer antraštės yra ypatingas atvejis, kai veiks:
// išsiuntė antraštę "Referrer: http://google.com" req.header("Referer"); // => "http://google.com" req.header("Referrer"); // => "http://google.com"
req.accepts(type)
Patikrina, ar patvirtinta antraštė buvo priimta ir ar ji atitinka nurodytą tipą.
Kai nėra antraštės Priimti, grąžinama tiesa. Kitu atveju tipas sutampa ir potipiai tikrinami. Galima perduoti „html“, kuris viduje konvertuojamas į „text/html“, naudojant MIME paieškos lentelę.
// Priimti: text/html req.accepts("html"); // => tiesa // Priimti: tekstas/*; application/json req.accepts("html"); req.accepts("text/html"); req.accepts("tekstas/paprastas"); req.accepts("application/json"); // => true req.accepts("image/png"); req.accepts("png"); // => klaidinga
req.is(tipas)
Tikrina gaunamą užklausą dėl turinio tipo antraštės ir atitinka nurodytą MIME tipą.
// Leisti turinio tipui: text/html; charset=utf-8 req.is("html"); req.is("tekstas/html"); // => true // Tegul turinio tipas dabar yra application/json req.is("json"); req.is("programa/json"); // => true req.is("html"); // => klaidinga
„Express“ galite užregistruoti savo atgalinius skambučius įvairiems užklausų patikrinimams. Pavyzdžiui, tarkime, kad turime gerai patikrinti, ar gaunama užklausa yra vaizdas. Norėdami tai padaryti, galite užregistruoti „vaizdo“ atgalinį skambutį:
app.is("vaizdas", function(req) ( return 0 == req.headers["content-type"].indexOf("vaizdas"); ));
Dabar galite jį naudoti maršruto tvarkyklėse norėdami patikrinti formos „image/jpeg“, „image/png“ ir kt. turinio tipą.
app.post("/image/upload", function(req, res, next) ( if (req.is("vaizdas")) ( // atlikti tam tikrus veiksmus ) else ( next(); ) ));
Nepamirškite, kad šis metodas taikomas ne tik turinio tipui – galite atlikti bet kokius patikrinimus.
Taip pat galite naudoti pakaitos simbolius. Tai supaprastins mūsų vaizdo pavyzdį. Čia patikrinsime tik tipą:
req.is("vaizdas/*");
Taip pat galime patikrinti potipį, kaip parodyta toliau. Čia „application/json“ ir „text/json“ atvejais patikrinimas bus teisingas.
req.is("*/json");
req.param(vardas[, numatytasis])
Grąžina parametro pavadinimo reikšmę arba, jei jos nėra, numatytąją reikšmę.
Tikrina maršruto parametrus (req.params), pvz., /user/:id
Tikrina užklausos eilutės parametrus (req.query), pavyzdžiui, ?id=12
Tikrina užklausos turinio URL koduotus parametrus (req.body), pvz., id=12
Norint gauti urlencode užklausos turinio parametrus, turi egzistuoti req.body objektas. Norėdami tai padaryti, įjunkite bodyParser() sluoksnį.
req.get(laukas, parametras)
Gauna antraštės lauko parametrą. Numatytoji eilutė yra tuščia.
req.get("turinio išdėstymas", "failo pavadinimas"); // => "something.png" req.get("Turinio tipas", "riba"); // => "--foo-bar-baz"
req.flash (tipas[, žinutė])
Sukuria iššokančiojo pranešimo eilę.
req.flash("informacija", "el. laiškas išsiųstas"); req.flash("klaida", "el. pašto pristatymas nepavyko"); req.flash("informacija", "el. laiškas išsiųstas pakartotinai"); // => 2 req.flash("info"); // => ["el. laiškas išsiųstas", "el. laiškas išsiųstas pakartotinai"] req.flash("info"); // => req.flash(); // => ( klaida: ["el. pašto pristatymas nepavyko"], informacija: )
Iššokančiuose pranešimuose taip pat gali būti naudojamos formatų eilutės. Galima numatytoji eilutė „%s“:
req.flash("informacija", "el. pašto pristatymas į _%s_ iš _%s_ nepavyko.", Vartotojui, Vartotojui);
req.isXMLHttpRequest
Taip pat sutrumpintai req.xhr. Patikrina antraštę X-Requested-With, kad sužinotų, ar užklausa buvo pateikta naudojant XMLHttpRequest:
req.xhr req.isXMLHttpRequest
Atsakymas
res.header(key[, val])
Gauna arba nustato atsakymo antraštę.
res.header("Turinio ilgis"); // => undefined res.header("Turinio ilgis", 123); // => 123 res.header("Turinio ilgis"); // => 123
res.charset
Nustato toliau nurodytų turinio tipo antraščių kodavimą. Pavyzdžiui, res.send() ir res.render() pagal numatytuosius nustatymus bus „utf8“ ir mes galime aiškiai nustatyti kodavimą prieš pateikiant šabloną:
res.charset = "ISO-8859-1"; res.render("vartotojai");
arba prieš atsakant res.send() :
res.charset = "ISO-8859-1"; res.send(str);
arba naudojant Node integruotą res.end() :
res.charset = "ISO-8859-1"; res.header("Turinio tipas", "tekstas/paprastas"); res.end(str);
res.contentType(tipas)
Nustato turinio tipo atsakymo antraštę.
var failo pavadinimas = "kelias/į/vaizdas.png"; res.contentType(failo pavadinimas); // Turinio tipas dabar yra „image/png“
Taip pat galite nustatyti turinio tipą naudodami šią eilutę:
res.contentType("application/json");
Arba tiesiog failo plėtinys (be priekinio taško):
res.contentType("json");
res.attachment()
Nustato turinio išdėstymo atsakymo antraštę į „priedas“ . Pasirinktinai galima perduoti failo pavadinimą.
res.attachment("path/to/my/image.png");
res.sendfile(kelias[, parinktys[, atgalinis skambutis]])
Naudojamas res.download() savavališkam failui perkelti.
res.sendfile("kelias/į/mano.failas");
Šis metodas priima pasirenkamą atgalinio skambinimo parametrą, kuris iškviečiamas, jei failo perkėlimas nepavyksta arba sėkmingas. Pagal numatytuosius nustatymus iškviečiamas next(err), bet jei perduodamas atgalinis skambutis, tai turi būti daroma aiškiai arba pašalinama klaida.
res.sendfile(kelias, funkcija(err) ( if (err) ( next(err); ) else ( console.log("perkeltas %s", kelias); ) ));
Taip pat galite perduoti parinktis fs.createReadStream() iškvietimui. Pavyzdžiui, norėdami pakeisti buferio dydį:
res.sendfile(path, ( bufferSize: 1024 ), function(err) ( // apdorojimas... ));
res.download(failas[, failo pavadinimas[, atgalinis skambutis[, atgalinis skambutis]]])
Įkelkite šį failą kaip priedą (galite nurodyti pasirenkamą alternatyvų failo pavadinimą).
res.download('path/to/image.png');
res.download('path/to/image.png', 'foo.png');
Tai atitinka šiuos dalykus:
res.attachment(failas); res.sendfile(failas);
Pasirinktinai galite nurodyti atšaukimą kaip antrą arba trečią res.sendfile() argumentą. Jame galite atsakyti taip, lyg antraštė dar nebūtų išsiųsta.
res.download(path, "expenses.doc", function(err) ( // apdorojimas... ));
Taip pat pasirinktinai galite perduoti antrąjį atgalinį skambutį2. Jis tvarko su ryšiu susijusias klaidas. Tačiau jis neturėtų bandyti siųsti atsakymo.
res.download(path, function(err) ( // klaida arba nutraukimas), function(err) ( // ryšio klaida ));
res.send(body|status[, headers|status[, status]])
Metodas res.send() yra aukšto lygio atsako priemonė, leidžianti perduoti objektus (JSON atsakymui), eilutes (HTML atsakui), buferio egzempliorius arba sveikuosius skaičius, nurodančius būsenos kodą (404, 500 ir kt. .) . Štai kaip jis naudojamas:
res.send(); // 204 res.send(new Buffer("wahoo")); res.send(( kai kurie: "json" )); res.send(""); res.send("Atsiprašome, negaliu rasti", 404); res.send("tekstas", ( "Turinio tipas": "tekstas/paprastas"), 201); res.send(404);
Pagal numatytuosius nustatymus turinio tipo antraštė nustatoma automatiškai. Tačiau jei jis buvo nustatytas rankiniu būdu tiesiogiai lauke res.send() arba prieš naudojant res.header() arba naudojant res.contentType() , tada jis nebus automatiškai nustatytas.
Atminkite, kad šis metodas baigia atsakymą (panašiai kaip res.end()), taigi, jei reikia pateikti kelis atsakymus arba srautą, turite naudoti res.write() .
res.json(obj[, antraštės|būsena[, būsena]])
Siunčia JSON atsakymą su pasirenkamomis antraštėmis ir būsenos kodu. Šis metodas idealiai tinka organizuoti JSON API, tačiau JSON taip pat galima siųsti naudojant res.send(obj) (tai nėra idealu, jei norite siųsti tik JSON koduotą eilutę, nes res.send(string) atsiųs HTML).
res.json(null); res.json(( vartotojas: "tj" )); res.json("sargybinis!", 500); res.json ("Nieko nerasta", 404);
res.redirect(url[, status])
Peradresuoja į nurodytą URL. Numatytasis būsenos kodas yra 302.
res.redirect("/", 301); res.redirect("/account"); res.redirect("http://google.com"); res.redirect("namai"); res.redirect("atgal");
„Express“ palaiko peradresavimų sparčiuosius klavišus – numatytieji yra „atgal“ ir „namai“ . Šiuo atveju „atgal“ peradresuoja į URL, nurodytą nukreipiančiojo (arba nukreipiančiojo) antraštėje, o „pagrindinis“ naudoja nustatymą „pagrindinis“ (numatytasis „/“).
res.cookie(vardas, val[, parinktys])
Nustato slapuko pavadinimu pavadinimą į val . Parinktys: tik http, saugus, baigiasi galiojimas ir kt. Numatytoji kelio parinktis yra reikšmė, nustatyta „namų“ nustatyme, paprastai „/“ .
// "Prisimink mane" 15 minučių res.cookie("prisiminti", "taip", ( expires: new Date(Data.now() + 900000), httpOnly: true ));
Ypatybės maxAge galiojimo laikas gali būti nustatytas pagal Date.now() milisekundėmis. Taigi mūsų aukščiau pateiktas pavyzdys dabar gali būti perrašytas taip:
res.cookie("prisiminti", "taip", ( maxAmžius: 900000 ));
Norėdami išanalizuoti gaunamus slapukus, naudokite cookieParser sluoksnį, kuris generuoja objektą req.cookies:
app.use(express.cookieParser()); app.get("/", function(req, res) ( // naudoti req.cookies.rememberme ));
res.clearCookie(vardas[, parinktys])
Išvalome slapuką pavadinimu name , priskirdami parametro galiojimo pabaigos datą tolimoje praeityje. Parinktys yra tokios pačios kaip ir res.cookie() , kelio taip pat numatytasis nustatymas „namai“.
res.clearCookie("prisiminti");
res.render(view[, options[, fn]])
Pateikiamas vaizdas su nurodytomis parinktimis ir pasirenkamu fn atgaliniu skambučiu. Kai pateikiamas fn, atsakymas klientui nėra automatinis, kitu atveju pateikiamas tekstas/html atsakymas su kodu 200 .
Perduotos parinktys taip pat yra vietinio rodinio kintamieji. Pavyzdžiui, jei norime perduoti vartotojo kintamąjį ir išjungti išdėstymą, tai darome viename objekte:
var user = ( vardas: "tj" ); res.render("indeksas", ( maketas: false, user: user ));
Parinkčių objektas taip pat naudojamas parinktims perduoti. Pavyzdžiui, jei perduodate būsenos ypatybę, ji ne tik tampa pasiekiama rodiniui, bet ir nustato atsakymo būsenos kodą. Tai taip pat naudinga, jei šablono variklis priima tam tikras parinktis, pvz., derinti arba suspausti . Žemiau pateikiamas pavyzdys, kaip galite pateikti klaidos puslapį – čia perduodama būsena ir norint jį rodyti, ir nustatyti būsenos kodą res.statusCode.
res.render("klaida", ( būsena: 500, pranešimas: "Vidinė serverio klaida" ));
res.partial(peržiūrėti[, parinktys])
Pateikiamas fragmentas su nurodytomis parinktimis. Šis metodas visada pasiekiamas iš rodinio kaip vietinis kintamasis.
- objektas – objektas perduotas vaizdui
- kaip ir kintamojo, kuris reprezentuos objekto objektą arba kiekvieną rodiniui perduotą kolekcijos elementą, pavadinimas. Numatytasis yra rodinio pavadinimas.
- kaip: "kažkas" - pridės vietinį kintamąjį kažką
- kaip: tai – rinkinio elementas bus naudojamas kaip peržiūros kontekstas (tai)
- kaip: globalus – sujungs rinkinio elemento ir vietinio rodinio kintamųjų savybes
- kolekcija – objektų masyvas. Jo pavadinimas kilęs iš vaizdo pavadinimo. Pavyzdžiui, video.html viduje bus vaizdo objektas.
Šios konstrukcijos yra lygiavertės viena kitai, o kolekcijos pavadinimas, perduotas fragmentui, visada bus „filmas“ .
partial("teatras/filmas.jade", (rinkinys: filmai )); dalinis ("teatras/filmas.nefritas", filmai); partial("filmas.jade", (rinkinys: filmai )); dalinis("filmas.jade", filmai); dalinis("filmas", filmai); // Vaizdo viduje: moovie.director
Norėdami pakeisti vietinio kintamojo pavadinimą iš "movie" į "video", galite naudoti kaip parinktį:
partial("filmas", (rinkinys: filmai, kaip: "vaizdo įrašas" )); // Rodinio viduje: video.director
Taip pat galime padaryti, kad filme būtų ši reikšmė mūsų rodinyje, kad vietoj movie.director galėtume nurodyti this.director .
partial("filmas", (rinkinys: filmai, kaip: tai )); // Vaizdo viduje: tai.direktorius
Alternatyvus sprendimas yra išplėsti rinkinio elemento savybes į pseudoglobalius (iš tikrųjų vietinius) kintamuosius, naudojant kaip: global , tai yra sintaksinis cukrus:
partial("filmas", (rinkinys: filmai, kaip: pasaulinis )); // Vaizdo viduje: režisierius
Ta pati logika taikoma ne tik kolekcijoms, bet ir objektui fragmento rodinyje:
partial("filmas", ( objektas: filmas, kaip: tai )); // Rodinio viduje: this.director partial("movie", ( objektas: filmas, kaip: globalus )); // Vaizdo viduje: režisierius partial("filmas", ( objektas: filmas, kaip: "video" )); // Rodinio viduje: video.director partial("filmas", ( objektas: filmas )); // Filmo režisierius
Kai antrasis argumentas yra nerinkinys (be .length), jis traktuojamas kaip objektas. Šiuo atveju šio objekto vietinio kintamojo pavadinimas susidaro iš rodinio pavadinimo.
var movie = new Filmas("Košmaras prieš Kalėdas", "Timas Burtonas") partial("filmas", filmas) // => Vaizdo viduje: movie.director
Šios taisyklės išimtis yra tada, kai perduodamas paprastas objektas („()“ arba „naujas objektas“), tada jis laikomas vietiniu objektu ir nepasiekiamas pagal pavadinimą fragmento rodinyje. Pavyzdžiui, šiame pavyzdyje galima tikėtis, kad yra vietinis kintamasis "movie" , tačiau kadangi tai yra paprastas objektas, vietiniai kintamieji jau yra "director" ir "title" , tai yra, jo savybės:
var movie = ( pavadinimas: "Košmaras prieš Kalėdas", režisierius: "Tim Burton" ); dalinis ("filmas", filmas)
Tokiais atvejais, kai reikia perduoti paprastą objektą, tiesiog priskirkite jį kokiai nors ypatybei arba naudokite objekto ypatybę, kuri paveldės objekto pavadinimą iš failo pavadinimo. Žemiau pateikti pavyzdžiai yra lygiaverčiai:
partial("filmas", ( vietiniai: ( filmas: filmas )) partial("filmas", ( filmas: filmas )) partial("filmas", ( objektas: filmas ))
Tą pačią API galima naudoti iš maršruto, kad galėtumėte atsakyti naudodami HTML fragmentą per AJAX arba WebSockets, pavyzdžiui, galite pateikti vartotojų rinkinį tiesiai iš maršruto:
app.get("/users", function(req, res) ( if (req.xhr) ( // siunčia atsakymą kiekvienam vartotojui iš rinkinio // perduodamas rodiniui "user" res.partial("user", vartotojai) ) else ( // atsakyti su visu išdėstymu su vartotojų sąrašo puslapiu // kurio šablonas daro partial("user", users) // ir prideda kažkokią sąsają res.render("users", () vartotojai: vartotojai ) ) ));
res.local(vardas[, val.])
Gaukite arba nustatykite nurodytą vietinį kintamąjį. Vietiniai kintamieji šiuo atveju reiškia kintamuosius, perduodamus rodinio atvaizdavimo metodams, pvz., res.render() .
app.all("/movie/:id", function(req, res, next) ( Movie.get(req.params.id, function(err, movie)) ( // Padaro priskyrimą res.locals.movie = movie res .local("filmas", filmas )); app.get("/movie/:id", function(req, res) ( // vietinis kintamasis filmas jau yra // bet prireikus galime jį pridėti res.render("movie", ( displayReviews: true ) ); ));
res.locals(obj)
Priskirkite kelis vietinius kintamuosius naudodami nurodytą obj objektą. Tai yra lygiavertis:
res.local("foo", baras); res.local("baras", baz); res.locals(( foo: bar, bar, baz ));
Serveris
app.set(vardas[, vertė])
Nustatykite programos pavadinimo nustatymą į val arba gaukite pavadinimo parametro reikšmę, jei trūksta val:
app.set("views", __dirname + "/views"); app.set("rodymai"); // => ...kelias...
Taip pat galite pasiekti nustatymus naudodami programų nustatymus:
app.settings.views // => ...kelias...
app.enable(vardas)
Nustato vardo nustatymą į teisingą:
app.enable("tam tikras savavališkas nustatymas"); app.set("tam tikras savavališkas nustatymas"); // => true app.enabled("kažkoks savavališkas nustatymas"); // => tiesa
app.enabled(name)
Patikrina, ar pavadinimo nustatymas teisingas:
app.enabled("peržiūrėti talpyklą"); // => false app.enable("peržiūrėti talpyklą"); app.enabled("peržiūrėti talpyklą"); // => tiesa
app.disable(vardas)
Nustatykite pavadinimo nustatymą į false:
app.disable("tam tikras nustatymas"); app.set("tam tikras nustatymas"); // => false app.disabled("tam tikras nustatymas"); // => klaidinga
app.disabled(vardas)
Patikrina, ar pavadinimo nustatymas klaidingas:
app.enable("peržiūrėti talpyklą"); app.disabled("peržiūrėti talpyklą"); // => false app.disable("peržiūrėti talpyklą"); app.disabled("peržiūrėti talpyklą"); // => tiesa
app.configure(env|function[, function])
Nurodo atgalinio skambinimo funkciją, skirtą env aplinkai (arba visoms aplinkoms):
app.configure(function() ( // veikia visose aplinkose )); app.configure("development", function() ( // vykdoma tik "development" aplinkai));
app.redirect(vardas, val)
Res.redirect() galime apibrėžti sparčiuosius klavišus (programos srityje), kaip nurodyta toliau:
app.redirect("google", "http://google.com");
Dabar maršrute galime skambinti:
res.redirect("google");
Taip pat galite naudoti dinamines santrumpas:
app.redirect("komentarai", funkcija(req, res) ( return "/post/" + req.params.id + "/comments"; ));
Dabar galite atlikti šiuos veiksmus ir peradresavimas bus dinamiškai kuriamas pagal užklausos kontekstą. Jei iškvietėme maršrutą naudodami GET /post/12, mūsų peradresavimas bus /post/12/comments.
app.get("/post/:id", function(req, res) ( res.redirect("komentarai"); ));
Jei programa yra prijungta, res.redirect() atsižvelgs į programos prijungimo tašką. Pavyzdžiui, jei dienoraščio programa yra prijungta prie /blog , šis pavyzdys nukreips į /blog/posts:
res.redirect("/posts");
app.error(function)
Prideda klaidų tvarkyklės funkciją, kurios pirmasis parametras priims visas išimtis, kaip parodyta toliau. Atminkite, kad kelis kartus iškviečiant šį metodą galima nustatyti kelias klaidų tvarkykles, tačiau metodas turi iškviesti next(), jei nenori apdoroti pačios išimties:
app.error(function(err, req, res, next) ( res.send(err.message, 500); ));
app.helpers(obj)
Registruoja statinio vaizdo pagalbininkus.
app.helpers(( vardas: funkcija(pirmas, paskutinis) ( grįžti pirmas + ", " + paskutinis ), vardas: "tj", pavardė: "holowaychuk" ));
Mūsų vaizdas dabar gali naudoti vardo ir pavardės kintamuosius ir funkciją name().
<%= name(firstName, lastName) %>
„Express“ pagal numatytuosius nustatymus taip pat pateikia kelis vietinius kintamuosius:
- nustatymai – programos nustatymų objektas
- layout(path) nurodykite išdėstymą tiesiai iš rodinio vidaus
Šis metodas vadinamas app.locals() .
app.dynamicHelpers(obj) (#app.dynamic-helpers)
Registruoja dinaminio vaizdo pagalbininkus. Dinaminio rodinio pagalbinės priemonės yra tiesiog funkcijos, kurios atlieka res , req ir yra vykdomos serverio egzemplioriaus kontekste prieš pateikiant bet kokį rodinį. Tokios funkcijos grąžinama reikšmė tampa vietiniu kintamuoju, su kuriuo funkcija susieta.
app.dynamicHelpers(( sesija: function(req, res) ( return req.session; ) ));
Dabar visi mūsų rodiniai turės prieigą prie seanso – seanso duomenys bus pasiekiami kaip session.name ir pan.:
<%= session.name %>
app.lookup
Grąžina maršruto tvarkykles, susietas su nurodytu keliu.
Tarkime, yra šie maršrutai:
Galite naudoti paieškos funkciją, kad patikrintumėte, kurie maršrutai yra nurodyti. Tai gali būti naudinga aukštesnio lygio sistemoms, sukurtoms naudojant 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() slapyvardis yra tiesiog app.HTTP_METHOD() – be atgalinio iškvietimo argumento. Tai yra sumažinimas. Pavyzdžiui, tai yra lygiavertė:
app.lookup.get("/user"); app.get("/user");
Kiekviena grąžinta funkcija papildyta naudingomis savybėmis:
var fn = app.get("/user/:id/:op?"); fn.regexp // => /^\/user\/(?:([^\/]+?))(?:\/([^\/]+?)))?\/?$/i fn .keys // => ["id", "op"] fn.path // => "/user/:id/:op?" fn.method // => "GAUTI"
app.match
Grąžina atgalinio skambinimo funkcijų masyvą, kuris suaktyvinamas nurodytu URL, kuriame gali būti užklausos eilutė ir kt. Tai gali būti naudinga norint suprasti, kurie maršrutai gali reaguoti.
Tarkime, kad turime šiuos maršrutus:
app.get("/vartotojas/:id", funkcija() ()); app.put("/user/:id", function() ()); app.get("/user/:id/:op?", function() ());
Iškvietus atitiktį GET, bus pateiktos dvi funkcijos, nes paskutiniame maršrute :op yra pasirenkamas parametras.
app.match.get("/user/1"); // =>
O kitas skambutis grąžins tik vieną perskambinimą /user/:id/:op? .
app.match.get("/user/23/edit"); // =>
Taip pat galime naudoti all(), jei HTTP metodas mums nėra svarbus
app.match.all("/user/20"); // =>
Kiekviena funkcija turi šias savybes:
var fn = app.match.get("/user/23/edit"); fn.keys // => ["id", "op"] fn.params // => ( id: "23", op: "redaguoti" ) fn.method // => "GET"
app.mounted(fn)
Priskirkite fn atgalinį skambutį, kuris iškviečiamas, kai šis serveris perduodamas Server.use() .
var app = express.createServer(), dienoraštis = express.createServer(); blog.mounted(function(parent) ( //parent yra programa // tai dienoraštis )); app.use(blog);
app.register(ext, exports)
Susieja nurodytas šablono variklio eksportavimo ypatybes (eksportus) su šablono failo išoriniu plėtiniu.
app.register(".html", reikalauti("jade"));
Tai taip pat gali būti naudinga bibliotekoms, kurių pavadinimas tiksliai neatitinka šablono failo plėtinio. Gyvas pavyzdys - Haml.js, kuris yra įdiegtas npm-om kaip „hamljs“ ir galime jį užregistruoti naudodami „.haml“ šablonus, o ne „.hamljs“, kaip būtų numatytasis:
app.register(".haml", Reikalu("haml-js"));
Be to, app.register yra labai naudingas šablonų varikliams, kurių API neatitinka Express specifikacijų. Toliau pateiktame pavyzdyje .md plėtinį susiejame su atvaizdavimo priemone užsirašyk- failai. HTML formatu pateiksime tik pirmą kartą – siekdami geresnio našumo – ir palaikysime kintamąjį formos „(vardas)“ pakeitimą.
app.register(.md", ( kompiliuoti: function(str, options) ( var html = md.toHTML(str); return function(locals)) ( return html.replace(/\(([^)]+) \)/g, funkcija(_, pavadinimas) ( grąžinti vietinius; ) );
app.listen()
Mes susiejame programos serverio lizdą su host:port adresu. Numatytasis prievadas yra 3000, pagrindinis kompiuteris yra INADDR_ANY.
app.klausytis(); app.klausytis(3000); app.listen(3000, "n.n.n.n");
Prievado argumentas taip pat gali būti eilutė, nurodanti kelią į unix domeno lizdas:
app.listen("/tmp/express.sock");
Dabar pabandykime:
$ telnet /tmp/express.sock GET / HTTP/1.1 HTTP/1.1 200 Gerai Turinio tipas: tekstas/paprastas Turinio ilgis: 11 Sveiki, pasauli
Projekto dalyviai
Pagrindiniai projekto dalyviai buvo šie:
- TJ Holowaychuk („visionmedia“)
- Ciaran Jessup (ciaranj)
- Aaronas Heckmannas (aheckmannas)
- Guillermo Rauch (Guille)
Trečiųjų šalių moduliai
Šie moduliai veikia su Express arba yra sukurti ant jo:
- suteikia išteklių nukreipimą
- greitieji pranešimai, pateikiantys iššokančius pranešimus
- greitojo konfigūravimo palaikymas asinchroninei konfigūracijai (duomenų įkėlimas iš „Redis“ ir kt.)
- express-namespace – vardų erdvės maršrutuose
- express-expose tiesiog paskelbia JS kodą programos kliento pusėje
- express-params – app.param() plėtiniai
- express-mongoose – įskiepis, skirtas lengvai pateikti Mongoose užklausų rezultatus (ORM, skirtas MongoDB)
Node JS & Express Basics (III).
Supraskime, kas yra npm ir kam jis reikalingas. Įdiekite Express ir EJS šablonų variklį. Atliekame visus parengiamuosius darbus ir pradedame kurti savo svetainę NodeJS.Dabar su parametrais, kurie nuolat keisis.
Jei reikia sukurti nuorodą į tam tikrą reikšmę, po /mews/value . Tai pasikeis. Pavyzdžiui: 23, dalis ar bet kuri kita vertė.App.get("/news/:id", function(req, res)( res.send("ID yra - " + req.params.id); ));
Priklausomai nuo šio parametro, galime paimti duomenis iš duomenų bazės (duomenų bazės) ir rodyti konkretų straipsnį.
Mums reikia tam tikro html failo, kuriame perkelsime savo id duomenis ir, priklausomai nuo šių duomenų, parodysime tą ar kitą informaciją.
Mums reikia kai kurių šablono variklis.
„Express“ dėka galime naudoti kelis šablonų variklius.
Kadangi EJS yra pasirenkamas paketas, turime jį įdiegti.
Paspausk Enter
Po to jis bus įdiegtas mūsų projekte.
Tai leidžia perduoti duomenis į įvairius šablonus, o šie šablonai turės .ejs plėtinį.
Šiuose šablonuose galėsime rodyti savo html kodą kartu su į jį įdėtu js kodu (kintamaisiais, rodymo kilpomis ir daug daugiau).
Atsiras puslapio šablonas, kuris keisis priklausomai nuo į jį perkeltų duomenų.
Pirmas dalykas, kurį turime padaryti, yra nurodyti, kurį peržiūros variklį naudosime.
Vaizdo variklis iš esmės yra šablono variklis.
Kadangi jų yra labai daug, o mes pasirinkome EJS, turime tai nurodyti faile index.js.
Iš karto po programos kintamojo inicijavimo.
App.set("view-engine", "ejs");
Pagal numatytuosius nustatymus visi failai, kuriuos rodysime, bus ieškomi rodinių aplanke.
Tame pačiame lygyje, kur index.js, sukursime aplanką rodiniai.
Jame sukursime naują failą news.ejs. Tai bus savotiškas šablonas, kurį užpildysime.
Šiuose šablonuose galime įdėti dažniausiai naudojamą html kodą.
Naujienų puslapis.
Norėdami tai padaryti, man nereikia naudoti .send arba .sendFile metodo, bet man reikės metodo render().
Render() metodas paima norimą failą (šabloną) rodinių aplanke ir gali jį parodyti naršyklėje. Be to, jis gali perduoti tam tikrus parametrus šiam šablonui.
Plėtinys gali būti nenurodytas naudojant render() metodą. Tada galite perduoti kai kuriuos parametrus pačiam šablonui. Todėl mes perduodame objektą kaip antrą parametrą. Jame gali būti daug savybių ir reikšmių.
Tarkime, kad nusprendėme perduoti tam tikrą parametrą newsId su reikšme req.params.id – tai yra, reikšmė bus pats vadinamas id.
App.get("/news/:id", function(req, res)( render("news", (newsId: req.params.id)); ));
Taigi reikšmė bus perduota naujienų šablonui, kuris bus vadinamas newsId su vertės id .
Visa tai galime priimti ir rodyti news.ejs faile.
Šiek tiek pakeisime naujienų.ejs failą. ID rodysime puslapio pavadinime.
Viską galite rasti EJS šablonų variklio dokumentacijoje (nuoroda aukščiau).
Naujienų puslapis su ID =<%= newsId %>
Failas /views/news.ejs
Naujienų puslapis su 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 dolor sit amet, consectetur adipis. Maiores enim vitae dolore nemo quas aliquam quia corrupti rerum ipsam ad nesciunt, architecto, pariatur officiis. Maxime iste ullam quibusdam, nobis voluptas!
index.js failą
Leisti išreikšti = reikalauti("išreikšti"); tegul programa = express (); app.set("peržiūros variklis", "ejs"); app.get("/", function(req, res)( res.sendFile(__dirname + "/index.html"); )); app.get("/apie", function(req, res)( res.sendFile(__dirname + "/about.html"); )); app.get("/news/:id", function(req, res)( res.render("news", (newsId: req.params.id)); )); app.klausytis(8080);
Galime perduoti kelis parametrus. Pavyzdžiui:
App.get("/news/:id", function(req, res)( res.render("news", (newsId: req.params.id, newParam: 535 )); ));
O naujienų.ejs faile mes jį parodysime puslapyje, pavyzdžiui, taip:
<%= newParam %>
Be to, galime perleisti savo objektus. Pavyzdžiui, sukurkime objektą:
App.get("/news/:id", function(req, res)( tegul obj = (pavadinimas:"Naujienos", id: 4); res.render("naujienos", (naujienos ID: req.params.id, newParam: 535)); ));
Ir mes taip pat galime perduoti šį objektą. Pirmiausia nustatome pavadinimą, ką perduosime, o tada nurodome, ką perduodame.
Pavyzdžiui:
App.get("/news/:id", function(req, res)( tegul obj = ( title:"Naujienos", id: 4); res.render("news", (newsId: req.params.id , newParam: 535, obj: obj ));
Pavadinimas =<%= obj.title %>
ID=<%= obj.id %>
<%= newParam %>
Masyvo perdavimas į šabloną.
Sukurkime duomenų masyvą ir parodykime jį naudodami kilpą.App.get("/news/:id", function(req, res)( tegul obj = ( title:"Naujienos", id: 4, pastraipos:["Pastraipa", "Paprastas tekstas", "Skaičiai: 3, 7, 24", 476]); res.render("naujienos", (newsId: req.params.id, newParam: 535, obj: obj)); ));
Dabar pačiame šablone mes tiesiog išvesime šį masyvą cikle:
-
<% obj.paragraphs.forEach(function(item) { %>
- <%= item %> <% }); %>
Statiniai failai ir tarpinė programinė įranga.
Failai, kurie gali būti įtraukti į kitus failus.
Dabar turime vieną šabloną – news.ejs, bet įsivaizduokite. kad jų yra daug. Tuzinai. Ir jums reikės pakeisti tam tikrą kodo dalį, kuri rodoma visuose šiuose failuose. Reikės padaryti daug pakeitimų.Norėdami to išvengti, galite naudoti failus, kurie gali būti įtraukti į kitus failus. Pavyzdžiui. Yra failas su svetainės antrašte. Ir jei jums reikia ką nors pakeisti, pakanka pakeisti tik vieną failą, nes jis tiesiog prisijungia prie kitų.
Rodinių šablonų aplanke sukurkite aplanką blokai ir jame failą hrader.ejs.
Failas hrader.ejs
- Į pagrindinį
- Apie mus
- žinios
Dabar turime įtraukti šį failą į visus šablonus. Eikite į naujienų failą ir iškart po atidarymo body žymės parašykite:
<% include blocks/header.ejs %>
Kelias nurodomas rodinių aplanke, nes šablono variklis visada pradeda ieškoti ten.
Statiniai failai.
Sukurkime naują aplanką index.js lygiu, vadinamą viešuoju. Jame bus visi statiniai failai. Tai css failai, nuotraukos, dokumentai ir tt Visi tie failai. kuri bus skambinama iš įvairių mūsų svetainės puslapių.Šiame aplanke sukursime kitą aplanką – css ir jame sukursime failą style.css.
Į jį perkelsime visą stiliaus kodą iš failo index.ejs
Į .ejs failus įtraukiame šiuos stilius:
Jei patikrinsite dabar, nieko neatsitiks. Stiliai nesusijungs.
Norėdami įtraukti statinius failus, turime naudoti tarpinę programinę įrangą:
Failo index.js viršuje, iškart po app.set , turėtume parašyti:
App.use("/public",);
O dabar, jei kur nors panaudosime nuorodą, prasidedančią /public, NodeJS ir Express pats supras, ką naudojame statinius failus ir viskas susijungs teisingai.
Antroje vietoje mes jų ieškome express.static("public"), ty aplanke /public.
Apibendrinant, kode app.use("/public", express.static("public")); stebime nuorodą, kurią įrašome
Jei būtų taip:
Tada šiame kode tai būtų:
App.use("/assets", express.static("public"));
Šiuo atveju viešas rodo aplanką!
Jei paliksite taip, jokių pakeitimų nebus. Failas bus prijungtas, nes stebėsime išteklių nuorodą.
App.use("/assets ", express.static("public "));
Kad būtų išvengta painiavos, jie paprastai pateikia nuorodą ir aplanką tuo pačiu pavadinimu. Dažniausiai tai yra vieša.
Tarpinė programinė įranga yra tai, ką mes darome prieš siųsdami bet kokius duomenis į puslapį (serverį).
Šiuo atveju tai yra mūsų tarpinė programinė įranga.
HTML formos kūrimas ir duomenų gavimas
Pirmas dalykas, kurį mes padarysime, yra įtraukti pačią formą į mūsų svetainę.Atidarykite failą about.ejs ir čia pridėsime formą naudodami įkrovos technologiją.
Į paieškos langą įveskite Forms ir nukopijuokite pirmąją formą iš rasto puslapio viršaus.
Išsaugokime ir bėgkime.
POST užklausa.
Kadangi vykdysime POST užklausą, į formą turime įtraukti keletą atributų.Method="post" – nes POST užklausa
Ir action="" yra vieta, kur reikia nukreipti vartotoją, kai jis spusteli "Pateikti". Mūsų atveju tai yra:
![mob_info](https://mapstr.ru/wp-content/themes/kuzov/pic/mob_info.png)