Express/Node introduction - 學習該如何開發Web | MDN
文章推薦指數: 80 %
Node (或者說Node.js) 是一個開源、跨平台和允許開發者使用Javascript創造伺服器端工具和應用 ... 此教學不會告訴建議的檔案名稱或如何執行該檔案;-).
SkiptomaincontentSkiptosearchSkiptoselectlanguage學習該如何開發Web伺服端網站程式設計Expresswebframework(Node.js/JavaScript)Express/NodeintroductionArticleActions正體中文(繁體)ThispagewastranslatedfromEnglishbythecommunity.LearnmoreandjointheMDNWebDocscommunity.什麼是Express和Node?歷史Node/Express有多流行?IsExpressopinionated?Express的程式碼長怎樣?總結SeealsoInthismoduleRelatedTopics
全新手請從這開始!
Web入門
Web概述
安裝基本軟體
自己的網站會是什麼樣子?
處理檔案
HTML基礎概念
CSS基礎概念
JavaScript基礎概念
發佈自己的網站
Web運作的方式
HTML—架構Web
HTML介紹
HTML概述
HTML入門
標題裡是什麼?HTML中的後設資料(Metadata)
HTML文字基礎概念
建立超連結
進階文字格式
文件與網站架構
HTML除錯
親和度:設個字母
親和度:架構出具備內容的網頁
多媒體與嵌入
多媒體與嵌入的概述
HTML中的圖片
視訊與音訊內容
從物件到iframe—其他嵌入技巧
為Web新增向量圖
適應性圖片
親和度:Mozilla形象頁面
HTML表格
HTML表格概述
HTML表格基礎
HTMLtableadvancedfeaturesandaccessibility
Assessment:Structuringplanetdata
CSS—設計Web的風格
初探CSS
初探CSS(概述)
CSS是什麼?
CSS入門
HowCSSisstructured
CSS怎麼運作
Assessment:Stylingabiographypage
CSS組件
CSSbuildingblocksoverview
Cascadeandinheritance
CSSselectors
Theboxmodel
Backgroundsandborders
Handlingdifferenttextdirections
Overflowingcontent
CSSvaluesandunits
SizingitemsinCSS
Images,media,andformelements
Stylingtables
DebuggingCSS
OrganizingyourCSS
Assessment:FundamentalCSScomprehension
Assessment:Creatingfancyletterheadedpaper
Assessment:Acool-lookingbox
樣式化文字
樣式化文字概述
基礎的文字與字型樣式化
樣式化列表
樣式化連結
Web字型
親合度:設定社區大學首頁的版面
CSS版面配置
CSS版面配置概述
IntroductiontoCSSlayout
NormalFlow
彈性區塊
格線
浮動
定位
Multiple-columnlayout
Responsivedesign
Beginner'sguidetomediaqueries
Legacylayoutmethods
Supportingolderbrowsers
Assessment:Fundamentallayoutcomprehension
JavaScript—動態的用戶端指令
JavaScript第一步
JavaScript第一步概述
什麼是JavaScript?
初次接觸JavaScript
出了什麼問題?JavaScript疑難排解
儲存你所需的資訊—變數
JavaScript基礎概念—數字與運算子
處理文字—JavaScript中的字串
有用的字串函式
陣列
親合度:傻瓜故事產生器
JavaScript基礎要件
JavaScript基礎要件概述
於程式碼中決策—條件
程式碼迴圈
函式—可重複使用的程式碼區塊
建立自己的函式
函式回傳值
事件介紹
親合度:圖庫
JavaScript物件介紹
JavaScript物件概述
物件基礎概念
物件原型
Object-orientedprogrammingconcepts
ClassesinJavaScript
使用JSON資料
物件建構實作
親合度:為彈跳球展示新增功能
非同步的JavaScript
AsynchronousJavaScriptoverview
IntroducingasynchronousJavaScript
Howtousepromises
Implementingapromise-basedAPI
Introducingworkers
Assessment:sequencinganimations
客戶端webAPIs
客戶端webAPIs
IntroductiontowebAPIs
文件操作
Fetchingdatafromtheserver
ThirdpartyAPIs
Drawinggraphics
VideoandaudioAPIs
Client-sidestorage
網頁表單-與使用者資料合作
核心的表單學習途徑
網頁表單概述
Yourfirstform
如何建構網頁表單
Basicnativeformcontrols
TheHTML5inputtypes
Otherformcontrols
Stylingwebforms
Advancedformstyling
UIpseudo-classes
Client-sideformvalidation
Sendingformdata
深入網頁表單
Howtobuildcustomformcontrols
SendingformsthroughJavaScript
CSSpropertycompatibilitytableforformcontrols
無障礙網頁—每個人都可以使用的網頁
無障礙網頁指南
無障礙網頁概述
何謂無障礙網頁?
HTML:Agoodbasisforaccessibility
CSSandJavaScriptaccessibilitybestpractices
WAI-ARIA基礎
Accessiblemultimedia
行動裝置上的無障礙
無障礙網頁評估
Assessment:Accessibilitytroubleshooting
MathML—WritingmathematicswithMathML
MathMLfirststeps
MathMLfirststepsoverview
GettingstartedwithMathML
Assessment:Threefamousmathematicalformulas
工具與測試
Client-sidewebdevelopmenttools
Client-sidewebdevelopmenttoolsindex
Client-sidetoolingoverview
Commandlinecrashcourse
Packagemanagementbasics
Introducingacompletetoolchain
Deployingourapp
介紹前端框架
前端框架簡介
Frameworkmainfeatures
React
GettingstartedwithReact
BeginningourReacttodolist
ComponentizingourReactapp
Reactinteractivity:Eventsandstate
Reactinteractivity:Editing,filtering,conditionalrendering
AccessibilityinReact
Reactresources
Ember
GettingstartedwithEmber
Emberappstructureandcomponentization
Emberinteractivity:Events,classesandstate
EmberInteractivity:Footerfunctionality,conditionalrendering
RoutinginEmber
Emberresourcesandtroubleshooting
Vue
開始學Vue
CreatingourfirstVuecomponent
RenderingalistofVuecomponents
Addinganewtodoform:Vueevents,methods,andmodels
StylingVuecomponentswithCSS
UsingVuecomputedproperties
Vueconditionalrendering:editingexistingtodos
FocusmanagementwithVuerefs
Vueresources
Svelte
Svelte入門
StartingourSvelteTodolistapp
DynamicbehaviorinSvelte:workingwithvariablesandprops
ComponentizingourSvelteapp
AdvancedSvelte:Reactivity,lifecycle,accessibility
WorkingwithSveltestores
TypeScriptsupportinSvelte
Deploymentandnextsteps
Angular
Angular新手入門
開始開發我們的Angular待辦事項應用程式
使用樣式點綴我們的Angular應用程式
建立一個item元件
篩選我們的待辦事項項目
建構Angular應用程式與更多資源
GitandGitHub
GitandGitHub概述
HelloWorld
GitHandbook
ForkingProjects
Aboutpullrequests
MasteringIssues
跨瀏覽器測試
跨瀏覽器測試概述
跨瀏覽器測試介紹
測試執行策略
處理常見的HTML與CSS問題
處理常見的JavaScript問題
處理常見的親合度問題
建置功能偵測
自動化測試介紹
設定自己的自動化測試環境
伺服端網站程式設計
第一步
第一步概述
伺服端介紹
用戶端概述
伺服端網路框架
網站安全
Django網站框架(Python)
Django網站框架(Python)概述
介紹
設定開發環境
線上教學:本地圖書館網站
線上教學2:建立網站骨架
線上教學3:使用模型
線上教學4:Django管理網站
線上教學5:建立我們的首頁
線上教學6:泛型清單與細節檢視
線上教學7:會話(Sessions)框架
線上教學8:使用者授權與許可
線上教學9:搭配表單
線上教學10:測試Django的WebApp
線上教學11:佈署Django至產品
WebApp安全性
親合度:DIY迷你部落格
Express網站框架(node.js/JavaScript)
Express網站框架(Node.js/JavaScript)概述
Express/Node介紹
設定Node(Express)的開發環境
Express教學1:本地圖書館網站
Express教學2:建立骨架網站
Express教學3:使用資料庫(Mongoose)
Express教學4:路由與控制器
Express教程5:呈現圖書館的資料
Express教學6:使用表單
Express教學7:佈署到正式環境
更多資源
常見問題
HTML問題
CSS問題
JavaScriptquestions
Web的運作方式
工具與設定
設計與親合度
什麼是Express和Node?歷史Node/Express有多流行?IsExpressopinionated?Express的程式碼長怎樣?總結SeealsoInthismoduleExpress/Nodeintroduction
Overview:ExpressNodejs
次頁
在這篇文章中回答了「什麼是Node?」和「什麼是Express」,同時概述是什麼讓Express框架如此特別。
本文將概述主要特性、展示一些Express應用的主要建構模塊(雖然此時你還沒有能測試它的開發環境)
前置需求:
基本的電腦知識。
對伺服器端網站程式設計的基本了解,特別是網站中客戶端-伺服器交互的機制(en-US)。
目標:
提升對Express的了解、如何與Node搭配使用、提供的功能和Express應用的主要建構模塊。
什麼是Express和Node?Node(或者說Node.js)是一個開源、跨平台和允許開發者使用Javascript創造伺服器端工具和應用的執行環境。
運行的目的是為了能在瀏覽器外使用,例如:直接執行在電腦或伺服器上。
所以該環境捨棄了瀏覽器限定的JavaScriptAPIs並增加更多傳統OSAPIs的支援,例如:HTTP和檔案系統的程式庫。
從網站伺服器開發的觀點來看Node有幾項優點:
高效能!Node旨在提升生產率和網頁應用的可擴充性。
而且它非常適合網站開發常見的問題,例如:即時網站應用
使用舊版本的JavaScript進行程式編寫,這表示不用多花力氣在轉換瀏覽器和伺服器上的程式碼
與其他傳統的Web伺服器語言(例如Python,PHP等)相比,JavaScript是一種相對新的程式語言,它受益於語言設計的改進。
許多其他新的和流行的語言都可以編譯/轉換成JavaScript,因此你還可以使用CoffeeScript,ClojureScript,Scala,LiveScript等
NodePackageManager(NPM)提供數十萬個第三方套件,是最佳的依賴解決方案也可以用來自動化大部分構建工具鏈。
它是可移植的,能夠在Windows,OSx,Linux,Solaris,FreeBSD,OpenBSD,WebOS和NonStopOS上執行。
許多web主機提供方也支援使用Node,通常會提供特定的基礎設施和文件
擁有非常活耀的第三方生態系統和開發者社群,許多人樂意提供幫助
你可以只用Node的HTTP模組創造一個簡單的web伺服器來回應任何請求,如下所示。
此教學不會告訴建議的檔案名稱或如何執行該檔案;-)
這將創造一個伺服器並會監聽http://127.0.0.1:8000/上任何種類的HTTP請求,當接收到任何請求時回傳一個「HelloWorld」的純文字回應。
//載入HTTP模組
varhttp=require("http");
//創建HTTP伺服器並監聽8000port
http.createServer(function(request,response){
//SettheresponseHTTPheaderwithHTTPstatusandContenttype
response.writeHead(200,{'Content-Type':'text/plain'});
//Sendtheresponsebody"HelloWorld"
response.end('HelloWorld\n');
}).listen(8000);
//PrintURLforaccessingserver
console.log('Serverrunningathttp://127.0.0.1:8000/');
Node並不原生支持其他常見的web開發任務,如果你想為不同的HTTP方法(例如:GET,POST,DELETE等)增加特定的處理、替不同的URL路徑提供靜態檔案、使用樣板或動態性的產生response,你需要自己完成相關的程式或者是避免重新造輪子-使用web框架!
Express是最受歡迎的Nodeweb框架,還是其他許多流行的Nodeweb框架的底層庫,它提供:
替不同HTTPMethod、不同URL路徑的requests編寫不同的處理方法
透過整合「畫面」的渲染引擎來達到插入資料到樣板中產生response
設定常見的web應用設定,例如:連線用的port和產生response的樣板位置
在request的處理流程中增加額外的「中間層」進行處理
雖然Express本身非常簡單,但開發者們已經創造相容的中間層套件來解決大部份web開發的問題,這些套件能處理cookies,sessions,登入,URL參數,POST資料,安全標頭等等,你能在ExpressMiddleware中找到這些套件的列表(以及其他流行的第三方套件)
備註:這種靈活性是一把雙刃劍。
有一些中間層套件能解決大部份的問題或需求,但使用正確的套件有時會是一個問題。
也沒有「正確的方法」來創建應用,你在網路上找到的範例也並非都是最佳解或是只有開發上所需要做的一小部份。
歷史2009年Node在Linux平台上初次發佈.2010年NPM套件管利器發佈,2012年增加Windows的原生支援.現在的LTS版本為Nodev8.11.2,最新版本為Nodev10.1.0。
這只是它深厚歷史的一小片斷,欲知更多詳情請洽Wikipedia。
2010年11月Express初次發佈,現在的API版本為4.16。
你可以查閱更新紀錄來了解此版本做了甚麼更改或是從GitHub中了解詳細的歷史紀錄。
Node/Express有多流行?對於web框架而言流行度很重要,這代表他會不會被繼續更新、文件、附加套件和技術支援方面有多少資源
現在沒有一個明確的指標來評斷伺服器端框架的流行度,雖然有HotFrameworks透過計算GitHub的專案數量和StackOverflow的問題來衡量流行度。
更好的問題是,Node和Express是否「夠流行」以避免成為不流行的平台。
有沒有持續進步?需要時是否能得到幫助?能不能找到Express相關的工作?
從眾多使用Express的公司、貢獻程式碼的人數和那些提供免費/收費支援的人員來看,是的!Express是一個流行的框架。
IsExpressopinionated?Web框架通常自稱為"opinionated"或"unopinionated".
Opinionated指的是那些有「正確」方法解決特定問題的框架。
在特定的需求上他們通常能快速開發,因為正確的方法通常易懂且有良好的文件,然而在面對其他問題時則會失去靈活性。
這類型的框架通常傾向於提供較少的選擇和套件來解決問題。
反過來說Unopinionated框架,對於如何組合套件來解決問題尚有較少的限制,開發者可以更輕易的使用適當的套件來解決特定問題,儘管代價是你需要自己找到適合的套件。
Express是Unopinionated框架,你可以在request處理流程中使用任何相容套件,使用單一或複數個檔案來建構應用,有時候甚至會覺得擁有太多選擇了。
Express的程式碼長怎樣?傳統的資料驅動網站中,web應用程式會等待來自瀏覽器(或其他客戶端)的HTTPRequest,接收到Request後根據URL和可能夾帶的POST/GET資料來決定需要回應什麼動作,根據需要可能對資料庫進行讀寫或執行滿足Request所需的其他任務。
web應用程式會回應Response給瀏覽器,通常是藉由插入檢所到的資料到HTML模板中動態產生HTML頁面讓瀏覽器顯示。
ExpressprovidesmethodstospecifywhatfunctioniscalledforaparticularHTTPverb(GET,POST,SET,etc.)andURLpattern("Route"),andmethodstospecifywhattemplate("view")engineisused,wheretemplatefilesarelocated,andwhattemplatetousetorenderaresponse.YoucanuseExpressmiddlewaretoaddsupportforcookies,sessions,andusers,gettingPOST/GETparameters,etc.YoucanuseanydatabasemechanismsupportedbyNode(Expressdoesnotdefineanydatabase-relatedbehaviour).
Thefollowingsectionsexplainsomeofthecommonthingsyou'llseewhenworkingwithExpressandNodecode.HelloworldExpressFirstletsconsiderthestandardExpressHelloWorldexample(wediscusseachpartofthisbelow,andinthefollowingsections).
備註:IfyouhaveNodeandExpressalreadyinstalled(orifyouinstallthemasshowninthenextarticle),youcansavethiscodeinatextfilecalledapp.jsandrunitinabashcommandpromptbycalling:
./node./app.js
varexpress=require('express');
varapp=express();
app.get('/',function(req,res){
res.send('HelloWorld!');
});
app.listen(3000,function(){
console.log('Exampleapplisteningonport3000!');
});
Thefirsttwolinesrequire()(import)theexpressmoduleandcreateanExpressapplication.Thisobject,whichistraditionallynamedapp,hasmethodsforroutingHTTPrequests,configuringmiddleware,renderingHTMLviews,registeringatemplateengine,andmodifyingapplicationsettingsthatcontrolhowtheapplicationbehaves(e.g.theenvironmentmode,whetherroutedefinitionsarecasesensitive,etc.)
Themiddlepartofthecode(thethreelinesstartingwithapp.get)showsaroutedefinition.Theapp.get()methodspecifiesacallbackfunctionthatwillbeinvokedwheneverthereisanHTTPGETrequestwithapath('/')relativetothesiteroot.Thecallbackfunctiontakesarequestandaresponseobjectasarguments,andsimplycallssend()ontheresponsetoreturnthestring"HelloWorld!"
Thefinalblockstartsuptheserveronport'3000'andprintsalogcommenttotheconsole.Withtheserverrunning,youcouldgotolocalhost:3000inyourbrowsertoseetheexampleresponsereturned.ImportingandcreatingmodulesAmoduleisaJavaScriptlibrary/filethatyoucanimportintoothercodeusingNode'srequire()function.Expressitselfisamodule,asarethemiddlewareanddatabaselibrariesthatweuseinourExpressapplications.
Thecodebelowshowshowweimportamodulebyname,usingtheExpressframeworkasanexample.Firstweinvoketherequire()function,specifyingthenameofthemoduleasastring('express'),andcallingthereturnedobjecttocreateanExpressapplication.Wecanthenaccessthepropertiesandfunctionsoftheapplicationobject.
varexpress=require('express');
varapp=express();
Youcanalsocreateyourownmodulesthatcanbeimportedinthesameway.
備註:Youwillwanttocreateyourownmodules,becausethisallowsyoutoorganiseyourcodeintomanagableparts—amonolithicsingle-fileapplicationishardtounderstandandmaintain.Usingmodulesalsohelpsyoumanageyournamespace,becauseonlythevariablesyouexplicitlyexportareimportedwhenyouuseamodule.
Tomakeobjectsavailableoutsideofamoduleyoujustneedtoassignthemtotheexportsobject.Forexample,thesquare.jsmodulebelowisafilethatexportsarea()andperimeter()methods:
exports.area=function(width){returnwidth*width;};
exports.perimeter=function(width){return4*width;};
Wecanimportthismoduleusingrequire(),andthencalltheexportedmethod(s)asshown:
varsquare=require('./square');//Herewerequire()thenameofthefilewithoutthe(optional).jsfileextension
console.log('Theareaofasquarewithawidthof4is'+square.area(4));
備註:Youcanalsospecifyanabsolutepathtothemodule(oraname,aswedidinitially).
Ifyouwanttoexportacompleteobjectinoneassignmentinsteadofbuildingitonepropertyatatime,assignittomodule.exportsasshownbelow(youcanalsodothistomaketherootoftheexportsobjectaconstructororotherfunction):
module.exports={
area:function(width){
returnwidth*width;
},
perimeter:function(width){
return4*width;
}
};
ForalotmoreinformationaboutmodulesseeModules(NodeAPIdocs).UsingasynchronousAPIsJavaScriptcodefrequentlyusesasynchronousratherthansynchronousAPIsforoperationsthatmaytakesometimetocomplete.AsynchronousAPIisoneinwhicheachoperationmustcompletebeforethenextoperationcanstart.Forexample,thefollowinglogfunctionsaresynchronous,andwillprintthetexttotheconsoleinorder(First,Second).
console.log('First');
console.log('Second');
Bycontrast,anasynchronousAPIisoneinwhichtheAPIwillstartanoperationandimmediatelyreturn(beforetheoperationiscomplete).Oncetheoperationfinishes,theAPIwillusesomemechanismtoperformadditionaloperations.Forexample,thecodebelowwillprintout"Second,First"becauseeventhoughsetTimeout()methodiscalledfirst,andreturnsimmediately,theoperationdoesn'tcompleteforseveralseconds.
setTimeout(function(){
console.log('First');
},3000);
console.log('Second');
Usingnon-blockingasynchronousAPIsisevenmoreimportantonNodethaninthebrowser,becauseNodeisasinglethreadedevent-drivenexecutionenvironment."singlethreaded"meansthatallrequeststotheserverarerunonthesamethread(ratherthanbeingspawnedoffintoseparateprocesses).Thismodelisextremelyefficientintermsofspeedandserverresources,butitdoesmeanthatifanyofyourfunctionscallsynchronousmethodsthattakealongtimetocomplete,theywillblocknotjustthecurrentrequest,buteveryotherrequestbeinghandledbyyourwebapplication.
ThereareanumberofwaysforanasynchronousAPItonotifyyourapplicationthatithascompleted.ThemostcommonwayistoregisteracallbackfunctionwhenyouinvoketheasynchronousAPI,thatwillbecalledbackwhentheoperationcompletes.Thisistheapproachusedabove.
備註:Usingcallbackscanbequite"messy"ifyouhaveasequenceofdependentasynchronousoperationsthatmustbeperformedinorder,becausethisresultsinmultiplelevelsofnestedcallbacks.Thisproblemiscommonlyknownas"callbackhell".Thisproblemcanbereducedbygoodcodingpractices(seehttp://callbackhell.com/),usingamodulelikeasync,orevenmovingtoES6featureslikePromises.
備註:AcommonconventionforNodeandExpressistouseerror-firstcallbacks.Inthisconventionthefirstvalueinyourcallbackfunctionsisanerrorvalue,whilesubsequentargumentscontainsuccessdata.Thereisagoodexplanationofwhythisapproachisusefulinthisblog:TheNode.jsWay-UnderstandingError-FirstCallbacks(fredkschott.com).
CreatingroutehandlersInourHelloWorldExpressexample(seeabove),wedefineda(callback)routehandlerfunctionforHTTPGETrequeststothesiteroot('/').
app.get('/',function(req,res){
res.send('HelloWorld!');
});
Thecallbackfunctiontakesarequestandaresponseobjectasarguments.Inthiscasethemethodsimplycallssend()ontheresponsetoreturnthestring"HelloWorld!"Thereareanumberofotherresponsemethodsforendingtherequest/responsecycle,forexampleyoucouldcallres.json()tosendaJSONresponseorres.sendFile()tosendafile.
備註:Youcanuseanyargumentnamesyoulikeinthecallbackfunctions;whenthecallbackisinvokedthefirstargumentwillalwaysbetherequestandthesecondwillalwaysbetheresponse.Itmakessensetonamethemsuchthatyoucanidentifytheobjectyou'reworkingwithinthebodyofthecallback.
TheExpressapplicationobjectalsoprovidesmethodstodefineroutehandlersforalltheotherHTTPverbs,whicharemostlyusedinexactlythesameway:post(),put(),delete(),options(),trace(),copy(),lock(),mkcol(),move(),purge(),propfind(),proppatch(),unlock(),report(),mkactivity(),checkout(),merge(),m-``search(),notify(),subscribe(),unsubscribe(),patch(),search(),andconnect().
Thereisaspecialroutingmethod,app.all(),whichwillbecalledinresponsetoanyHTTPmethod.Thisisusedforloadingmiddlewarefunctionsataparticularpathforallrequestmethods.Thefollowingexample(fromtheExpressdocumentation)showsahandlerthatwillbeexecutedforrequeststo/secretirrespectiveoftheHTTPverbused(provideditissupportedbythehttpmodule).
app.all('/secret',function(req,res,next){
console.log('Accessingthesecretsection...');
next();//passcontroltothenexthandler
});
RoutesallowyoutomatchparticularpatternsofcharactersinaURL,andextractsomevaluesfromtheURLandpassthemasparameterstotheroutehandler(asattributesoftherequestobjectpassedasaparameter).
Oftenitisusefultogrouproutehandlersforaparticularpartofasitetogetherandaccessthemusingacommonroute-prefix(e.g.asitewithaWikimighthaveallwiki-relatedroutesinonefileandhavethemaccessedwitharouteprefixof/wiki/).InExpressthisisachievedbyusingtheexpress.Routerobject.Forexample,wecancreateourwikirouteinamodulenamedwiki.js,andthenexporttheRouterobject,asshownbelow:
//wiki.js-Wikiroutemodule
varexpress=require('express');
varrouter=express.Router();
//Homepageroute
router.get('/',function(req,res){
res.send('Wikihomepage');
});
//Aboutpageroute
router.get('/about',function(req,res){
res.send('Aboutthiswiki');
});
module.exports=router;
備註:AddingroutestotheRouterobjectisjustlikeaddingroutestotheappobject(asshownpreviously).
Tousetherouterinourmainappfilewewouldthenrequire()theroutemodule(wiki.js),thencalluse()ontheExpressapplicationtoaddtheRoutertothemiddlewarehandlingpath.Thetworouteswillthenbeaccessiblefrom/wiki/and/wiki/about/.
varwiki=require('./wiki.js');
//...
app.use('/wiki',wiki);
We'llshowyoualotmoreaboutworkingwithroutes,andinparticularaboutusingtheRouter,lateroninthelinkedsectionRoutesandcontrollers.UsingmiddlewareMiddlewareisusedextensivelyinExpressapps,fortasksfromservingstaticfilestoerrorhandling,tocompressingHTTPresponses.WhereasroutefunctionsendtheHTTPrequest-responsecyclebyreturningsomeresponsetotheHTTPclient,middlewarefunctionstypicallyperformsomeoperationontherequestorresponseandthencallthenextfunctioninthe"stack",whichmightbemoremiddlewareoraroutehandler.Theorderinwhichmiddlewareiscalledisuptotheappdeveloper.
備註:Themiddlewarecanperformanyoperation,executeanycode,makechangestotherequestandresponseobject,anditcanalsoendtherequest-responsecycle.Ifitdoesnotendthecyclethenitmustcallnext()topasscontroltothenextmiddlewarefunction(ortherequestwillbelefthanging).
Mostappswillusethird-partymiddlewareinordertosimplifycommonwebdevelopmenttaskslikeworkingwithcookies,sessions,userauthentication,accessingrequestPOSTandJSONdata,logging,etc.YoucanfindalistofmiddlewarepackagesmaintainedbytheExpressteam(whichalsoincludesotherpopular3rdpartypackages).OtherExpresspackagesareavailableontheNPMpackagemanager.
TousethirdpartymiddlewareyoufirstneedtoinstallitintoyourappusingNPM.Forexample,toinstallthemorganHTTPrequestloggermiddleware,you'ddothis:
npminstallmorgan
Youcouldthencalluse()ontheExpressapplicationobjecttoaddthemiddlewaretothestack:
varexpress=require('express');
varlogger=require('morgan');
varapp=express();
app.use(logger('dev'));
...
備註:Middlewareandroutingfunctionsarecalledintheorderthattheyaredeclared.Forsomemiddlewaretheorderisimportant(forexampleifsessionmiddlewaredependsoncookiemiddleware,thenthecookiehandlermustbeaddedfirst).Itisalmostalwaysthecasethatmiddlewareiscalledbeforesettingroutes,oryourroutehandlerswillnothaveaccesstofunctionalityaddedbyyourmiddleware.
Youcanwriteyourownmiddlewarefunctions,andyouarelikelytohavetodoso(ifonlytocreateerrorhandlingcode).Theonlydifferencebetweenamiddlewarefunctionandaroutehandlercallbackisthatmiddlewarefunctionshaveathirdargumentnext,whichmiddlewarefunctionsareexpectedtocalliftheyarenotthatwhichcompletestherequestcycle(whenthemiddlewarefunctioniscalled,thiscontainsthenextfunctionthatmustbecalled).
Youcanaddamiddlewarefunctiontotheprocessingchainwitheitherapp.use()orapp.add(),dependingonwhetheryouwanttoapplythemiddlewaretoallresponsesortoresponseswithaparticularHTTPverb(GET,POST,etc).Youspecifyroutesthesameinbothcases,thoughtherouteisoptionalwhencallingapp.use().
Theexamplebelowshowshowyoucanaddthemiddlewarefunctionusingbothmethods,andwith/withoutaroute.
varexpress=require('express');
varapp=express();
//Anexamplemiddlewarefunction
vara_middleware_function=function(req,res,next){
//...performsomeoperations
next();//Callnext()soExpresswillcallthenextmiddlewarefunctioninthechain.
}
//Functionaddedwithuse()forallroutesandverbs
app.use(a_middleware_function);
//Functionaddedwithuse()foraspecificroute
app.use('/someroute',a_middleware_function);
//AmiddlewarefunctionaddedforaspecificHTTPverbandroute
app.get('/',a_middleware_function);
app.listen(3000);
備註:Abovewedeclarethemiddlewarefunctionseparatelyandthensetitasthecallback.Inourpreviousroutehandlerfunctionwedeclaredthecallbackfunctionwhenitwasused.InJavaScript,eitherapproachisvalid.
TheExpressdocumentationhasalotmoreexcellentdocumentationaboutusingandwritingExpressmiddleware.ServingstaticfilesYoucanusetheexpress.staticmiddlewaretoservestaticfiles,includingyourimages,CSSandJavaScript(static()istheonlymiddlewarefunctionthatisactuallypartofExpress).Forexample,youwouldusethelinebelowtoserveimages,CSSfiles,andJavaScriptfilesfromadirectorynamed'public'atthesamelevelaswhereyoucallnode:
app.use(express.static('public'));
Anyfilesinthepublicdirectoryareservedbyaddingtheirfilename(relativetothebase"public"directory)tothebaseURL.Soforexample:
http://localhost:3000/images/dog.jpg
http://localhost:3000/css/style.css
http://localhost:3000/js/app.js
http://localhost:3000/about.html
Youcancallstatic()multipletimestoservemultipledirectories.Ifafilecannotbefoundbyonemiddlewarefunctionthenitwillsimplybepassedontothesubsequentmiddleware(theorderthatmiddlewareiscalledisbasedonyourdeclarationorder).
app.use(express.static('public'));
app.use(express.static('media'));
YoucanalsocreateavirtualprefixforyourstaticURLs,ratherthanhavingthefilesaddedtothebaseURL.Forexample,herewespecifyamountpathsothatthefilesareloadedwiththeprefix"/media":
app.use('/media',express.static('public'));
Now,youcanloadthefilesthatareinthepublicdirectoryfromthe/mediapathprefix.
http://localhost:3000/media/images/dog.jpg
http://localhost:3000/media/video/cat.mp4
http://localhost:3000/media/cry.mp3
Formoreinformation,seeServingstaticfilesinExpress.HandlingerrorsErrorsarehandledbyoneormorespecialmiddlewarefunctionsthathavefourarguments,insteadoftheusualthree:(err,req,res,next).Forexample:
app.use(function(err,req,res,next){
console.error(err.stack);
res.status(500).send('Somethingbroke!');
});
Thesecanreturnanycontentrequired,butmustbecalledafterallotherapp.use()androutescallssothattheyarethelastmiddlewareintherequesthandlingprocess!
Expresscomeswithabuilt-inerrorhandler,whichtakescareofanyremainingerrorsthatmightbeencounteredintheapp.Thisdefaulterror-handlingmiddlewarefunctionisaddedattheendofthemiddlewarefunctionstack.Ifyoupassanerrortonext()andyoudonothandleitinanerrorhandler,itwillbehandledbythebuilt-inerrorhandler;theerrorwillbewrittentotheclientwiththestacktrace.
備註:Thestacktraceisnotincludedintheproductionenvironment.TorunitinproductionmodeyouneedtosetthetheenvironmentvariableNODE_ENVto'production'.
備註:HTTP404andother"error"statuscodesarenottreatedaserrors.Ifyouwanttohandlethese,youcanaddamiddlewarefunctiontodoso.FormoreinformationseetheFAQ.
FormoreinformationseeErrorhandling(Expressdocs).UsingdatabasesExpressappscanuseanydatabasemechanismsupportedbyNode(Expressitselfdoesn'tdefineanyspecificadditionalbehaviour/requirementsfordatabasemanagement).Therearemanyoptions,includingPostgreSQL,MySQL,Redis,SQLite,MongoDB,etc.
InordertousetheseyouhavetofirstinstallthedatabasedriverusingNPM.Forexample,toinstallthedriverforthepopularNoSQLMongoDByouwouldusethecommand:
npminstallmongodb
Thedatabaseitselfcanbeinstalledlocallyoronacloudserver.InyourExpresscodeyourequirethedriver,connecttothedatabase,andthenperformcreate,read,update,anddelete(CRUD)operations.Theexamplebelow(fromtheExpressdocumentation)showshowyoucanfind"mammal"recordsusingMongoDB.
//thisworkswitholderversionsofmongodbversion~2.2.33
varMongoClient=require('mongodb').MongoClient;
MongoClient.connect('mongodb://localhost:27017/animals',function(err,db){
if(err)throwerr;
db.collection('mammals').find().toArray(function(err,result){
if(err)throwerr;
console.log(result);
});
});
//formongodbversion3.0andup
letMongoClient=require('mongodb').MongoClient;
MongoClient.connect('mongodb://localhost:27017/animals',function(err,client){
if(err)throwerr;
letdb=client.db('animals');
db.collection('mammals').find().toArray(function(err,result){
if(err)throwerr;
console.log(result);
client.close();
});
}
Anotherpopularapproachistoaccessyourdatabaseindirectly,viaanObjectRelationalMapper("ORM").Inthisapproachyoudefineyourdataas"objects"or"models"andtheORMmapsthesethroughtotheunderlyingdatabaseformat.ThisapproachhasthebenefitthatasadeveloperyoucancontinuetothinkintermsofJavaScriptobjectsratherthandatabasesemantics,andthatthereisanobviousplacetoperformvalidationandcheckingofincomingdata.We'lltalkmoreaboutdatabasesinalaterarticle.
FormoreinformationseeDatabaseintegration(Expressdocs).Renderingdata(views)Templateengines(referredtoas"viewengines"byExpress)allowyoutospecifythestructureofanoutputdocumentinatemplate,usingplaceholdersfordatathatwillbefilledinwhenapageisgenerated.TemplatesareoftenusedtocreateHTML,butcanalsocreateothertypesofdocuments.Expresshassupportforanumberoftemplateengines,andthereisausefulcomparisonofthemorepopularengineshere:ComparingJavaScriptTemplatingEngines:Jade,Mustache,DustandMore.
InyourapplicationsettingscodeyousetthetemplateenginetouseandthelocationwhereExpressshouldlookfortemplatesusingthe'views'and'viewengines'settings,asshownbelow(youwillalsohavetoinstallthepackagecontainingyourtemplatelibrarytoo!)
varexpress=require('express');
varapp=express();
//Setdirectorytocontainthetemplates('views')
app.set('views',path.join(__dirname,'views'));
//Setviewenginetouse,inthiscase'some_template_engine_name'
app.set('viewengine','some_template_engine_name');
Theappearanceofthetemplatewilldependonwhatengineyouuse.Assumingthatyouhaveatemplatefilenamed"index.
您還應該明白,Express是一個不固執己見的框架,您將這些組件組合在一起的方式以及您使用的函式庫,在很大程度上取決於您!
當然,Express是一個非常輕量級的Web應用程序框架,它的許多好處和潛力來自第三方函式庫和功能。
我們將在以下文章中更詳細地介紹這些內容。
在下一篇文章中,我們將介紹如何設置Node開發環境,以便您可以開始查看一些Express代碼。
Seealso
Venkat.R-ManageMultipleNodeversions
Modules(NodeAPIdocs)
Express(homepage)
Basicrouting(Expressdocs)
Routingguide(Expressdocs)
UsingtemplateengineswithExpress(Expressdocs)
Usingmiddleware(Expressdocs)
WritingmiddlewareforuseinExpressapps(Expressdocs)
Databaseintegration(Expressdocs)
ServingstaticfilesinExpress(Expressdocs)
Errorhandling(Expressdocs)
Overview:ExpressNodejs
次頁
Inthismodule
Express/Nodeintroduction
SettingupaNode(Express)developmentenvironment
ExpressTutorial:TheLocalLibrarywebsite
ExpressTutorialPart2:Creatingaskeletonwebsite
ExpressTutorialPart3:UsingaDatabase(withMongoose)
ExpressTutorialPart4:Routesandcontrollers
ExpressTutorialPart5:Displayinglibrarydata
ExpressTutorialPart6:Workingwithforms
ExpressTutorialPart7:Deployingtoproduction
Foundaproblemwiththispage?EditonGitHubSourceonGitHubReportaproblemwiththiscontentonGitHubWanttofixtheproblemyourself?SeeourContributionguide.Lastmodified:2022年9月20日,byMDNcontributors
延伸文章資訊
- 1[學習之路] Node.js 入門教學
注意每個node 版本都是獨立的npm 套件不共用。 USB 免安裝. 因為工作需要不同電腦上執行,因此我習慣用USB 作免安裝環境。因此VScode、GIT、Nodejs ...
- 2Node.js 教程| 菜鸟教程
Node.js 教程. nodejs. 简单的说Node.js 就是运行在服务端的JavaScript。 Node.js 是一个基于Chrome JavaScript 运行时建立 ...
- 3Express 教學2: 創建一個骨架網站- 學習該如何開發Web | MDN
使用應用產生器. 您應該已經安裝了生成器,作為設置Node 開發環境的一部分。作為快速提醒,您可以使用NPM 軟件包管理 ...
- 4教學課程:適用於初學者的Node.js - Microsoft Learn
必要條件 · 嘗試搭配Visual Studio Code 使用NodeJS · 使用Express 建立您的第一個NodeJS Web 應用程式 · 嘗試使用Node.js 模組.
- 5Express/Node introduction - 學習該如何開發Web | MDN
Node (或者說Node.js) 是一個開源、跨平台和允許開發者使用Javascript創造伺服器端工具和應用 ... 此教學不會告訴建議的檔案名稱或如何執行該檔案;-).