node.js進階
一、回顧與繼續
對於一種語言的認識都是經歷這樣的一個過程的,首先從原生的環境(CMD)中開始學習,找到一門語言之間各種引用的本質和相互之間的調用方式,明澈各種依賴關系,在這個基礎上我們可以進行一些比較簡單的編程,但是卻總是感覺到自己需要做很多底層的工作,開發的效率也比較低,因此在基本熟練的基礎上,我們就需要使用IDE這種集成開發環境來進行大規模項目的開發和對接了。而node.js同樣如此,在這里我推薦使用WebStorm來作為node.js的IDE,在這種環境中我們可以便於跟蹤和調試和執行,並且有着優質的性能和文件列表,下載與安裝也比較簡單,需要注意的是網上有很多破解方法,我們最好破解了再使用。上一章節中我們對node.js的起源,設計思想,以及簡單的程序運行進行了詳細的闡述和整理,在這一章節,我們繼續對node.js進行研究,將視線移向更遠的地方,大規模項目的開發和管理,仔細聯想一下我們開發Java程序,C++,C#程序的時候,我們總是離不開這些東西,包、命名空間、類、對象、調用、線程、同步異步、相對路徑、絕對路徑、環境變量、作用域等,同樣的,在node.js中,我們也有類似的概念,並且node.js因為有npm這樣的包管理工具,使得其具有很大的靈活性和方便性,我們可以方便的使用別人的代碼而不需要知道內部的細節,類似於服務的調用,這樣可以大大的節約我們的時間,並且減少開發的成本,這種設計思想使得node.js有很強的生命力!
二、WebStorm中的一些注意事項
首先,我們破解了軟件之后新建一個js文件,在里面可以輸入簡單的js執行語句,然后用shift+ctrl+F10或者shift+F10即可執行,同時可以在控制台輸出相應的結果,在這里我們要注意程序執行的機理,首先我們打開設置可以看到執行命令的其實就是我們一直以來使用的解釋器node.exe,並且還有一個工作目錄,這個目錄非常重要,如果我們選擇了和運行文件不一樣的位置可能導致文件無法執行。同樣的,讓我們運行一個最簡單的node.js程序,來看一下輸出的結果!
1 var http = require("http"); 2 //創建服務器
3 var server = http.createServer(function(req,res){ 4 //每次接受請求之后做的事情
5 //設置響應頭
6 res.writeHead(200,{"Content-Type":"text/html;charset=UTF8"}); 7 res.write("<ul>"); 8 res.write("<li>hello,world</li>"); 9 res.write("<li>hello,zyr</li>"); 10 res.write("</ul>"); 11 res.end("成功!"); 12 }); 13 server.listen(3100,"127.0.0.1");
讀取各種文件並顯示,通過異步操作和解析json完成:
1 var http = require("http"); 2 var fs = require("fs"); 3 var url = require("url"); 4 var path = require("path"); 5
6 var server = http.createServer(function(req,res){ 7 var pathname = url.parse(req.url).pathname; 8 //判斷此時用戶輸入的地址是文件夾地址還是文件地址
9 //如果是文件夾地址,那么自動請求這個文件夾中的index.html
10 if(pathname.indexOf(".") == -1){ 11 pathname += "/index.html"; 12 } 13 //輸入的網址是127.0.0.1/images/logo.png
14 //實際請求的是./static/images/logo.png
15 var fileURL = "./" + path.normalize("./static/" + pathname); 16 //得到拓展名
17 var extname = path.extname(pathname); 18
19 //把文件讀出來
20 fs.readFile(fileURL,function(err,data){ 21 //讀完之后做的事情
22 if(err){ 23 //文件不存在
24 res.writeHead(404,{"Content-Type":"text/html;charset=UTF8"}) 25 res.end("404,頁面沒有找到"); 26 } 27 //讀完之后做的事情
28 getMime(extname,function(mime){ 29 res.writeHead(200,{"Content-Type":mime}) 30 res.end(data); 31 }); 32 }); 33 }); 34
35 server.listen(3100,"127.0.0.1"); 36
37 function getMime(extname,callback){ 38 //讀取mime.json文件,得到JSON,根據extname key ,返回對應的value
39 //讀取文件
40 fs.readFile("./mime.json",function(err,data){ 41 if(err){ 42 throw Error("找不到mime.json文件!"); 43 return; 44 } 45 //轉成JSON
46 var mimeJSON = JSON.parse(data); 47 var mime = mimeJSON[extname] || "text/plain"; 48 //執行回調函數,mime類型字符串,就是它的參數
49 callback(mime); 50 }); 51 }
所使用的json文件:

{ ".323":"text/h323" , ".3gp":"video/3gpp" , ".aab":"application/x-authoware-bin" , ".aam":"application/x-authoware-map" , ".aas":"application/x-authoware-seg" , ".acx":"application/internet-property-stream" , ".ai":"application/postscript" , ".aif":"audio/x-aiff" , ".aifc":"audio/x-aiff" , ".aiff":"audio/x-aiff" , ".als":"audio/X-Alpha5" , ".amc":"application/x-mpeg" , ".ani":"application/octet-stream" , ".apk":"application/vnd.android.package-archive" , ".asc":"text/plain" , ".asd":"application/astound" , ".asf":"video/x-ms-asf" , ".asn":"application/astound" , ".asp":"application/x-asap" , ".asr":"video/x-ms-asf" , ".asx":"video/x-ms-asf" , ".au":"audio/basic" , ".avb":"application/octet-stream" , ".avi":"video/x-msvideo" , ".awb":"audio/amr-wb" , ".axs":"application/olescript" , ".bas":"text/plain" , ".bcpio":"application/x-bcpio" , ".bin ":"application/octet-stream" , ".bld":"application/bld" , ".bld2":"application/bld2" , ".bmp":"image/bmp" , ".bpk":"application/octet-stream" , ".bz2":"application/x-bzip2" , ".c":"text/plain" , ".cal":"image/x-cals" , ".cat":"application/vnd.ms-pkiseccat" , ".ccn":"application/x-cnc" , ".cco":"application/x-cocoa" , ".cdf":"application/x-cdf" , ".cer":"application/x-x509-ca-cert" , ".cgi":"magnus-internal/cgi" , ".chat":"application/x-chat" , ".class":"application/octet-stream" , ".clp":"application/x-msclip" , ".cmx":"image/x-cmx" , ".co":"application/x-cult3d-object" , ".cod":"image/cis-cod" , ".conf":"text/plain" , ".cpio":"application/x-cpio" , ".cpp":"text/plain" , ".cpt":"application/mac-compactpro" , ".crd":"application/x-mscardfile" , ".crl":"application/pkix-crl" , ".crt":"application/x-x509-ca-cert" , ".csh":"application/x-csh" , ".csm":"chemical/x-csml" , ".csml":"chemical/x-csml" , ".css":"text/css" , ".cur":"application/octet-stream" , ".dcm":"x-lml/x-evm" , ".dcr":"application/x-director" , ".dcx":"image/x-dcx" , ".der":"application/x-x509-ca-cert" , ".dhtml":"text/html" , ".dir":"application/x-director" , ".dll":"application/x-msdownload" , ".dmg":"application/octet-stream" , ".dms":"application/octet-stream" , ".doc":"application/msword" , ".docx":"application/vnd.openxmlformats-officedocument.wordprocessingml.document" , ".dot":"application/msword" , ".dvi":"application/x-dvi" , ".dwf":"drawing/x-dwf" , ".dwg":"application/x-autocad" , ".dxf":"application/x-autocad" , ".dxr":"application/x-director" , ".ebk":"application/x-expandedbook" , ".emb":"chemical/x-embl-dl-nucleotide" , ".embl":"chemical/x-embl-dl-nucleotide" , ".eps":"application/postscript" , ".epub":"application/epub+zip" , ".eri":"image/x-eri" , ".es":"audio/echospeech" , ".esl":"audio/echospeech" , ".etc":"application/x-earthtime" , ".etx":"text/x-setext" , ".evm":"x-lml/x-evm" , ".evy":"application/envoy" , ".exe":"application/octet-stream" , ".fh4":"image/x-freehand" , ".fh5":"image/x-freehand" , ".fhc":"image/x-freehand" , ".fif":"application/fractals" , ".flr":"x-world/x-vrml" , ".flv":"flv-application/octet-stream" , ".fm":"application/x-maker" , ".fpx":"image/x-fpx" , ".fvi":"video/isivideo" , ".gau":"chemical/x-gaussian-input" , ".gca":"application/x-gca-compressed" , ".gdb":"x-lml/x-gdb" , ".gif":"image/gif" , ".gps":"application/x-gps" , ".gtar":"application/x-gtar" , ".gz":"application/x-gzip" , ".h":"text/plain" , ".hdf":"application/x-hdf" , ".hdm":"text/x-hdml" , ".hdml":"text/x-hdml" , ".hlp":"application/winhlp" , ".hqx":"application/mac-binhex40" , ".hta":"application/hta" , ".htc":"text/x-component" , ".htm":"text/html" , ".html":"text/html" , ".hts":"text/html" , ".htt":"text/webviewhtml" , ".ice":"x-conference/x-cooltalk" , ".ico":"image/x-icon" , ".ief":"image/ief" , ".ifm":"image/gif" , ".ifs":"image/ifs" , ".iii":"application/x-iphone" , ".imy":"audio/melody" , ".ins":"application/x-internet-signup" , ".ips":"application/x-ipscript" , ".ipx":"application/x-ipix" , ".isp":"application/x-internet-signup" , ".it":"audio/x-mod" , ".itz":"audio/x-mod" , ".ivr":"i-world/i-vrml" , ".j2k":"image/j2k" , ".jad":"text/vnd.sun.j2me.app-descriptor" , ".jam":"application/x-jam" , ".jar":"application/java-archive" , ".java":"text/plain" , ".jfif":"image/pipeg" , ".jnlp":"application/x-java-jnlp-file" , ".jpe":"image/jpeg" , ".jpeg":"image/jpeg" , ".jpg":"image/jpeg" , ".jpz":"image/jpeg" , ".js":"application/x-javascript" , ".jwc":"application/jwc" , ".kjx":"application/x-kjx" , ".lak":"x-lml/x-lak" , ".latex":"application/x-latex" , ".lcc":"application/fastman" , ".lcl":"application/x-digitalloca" , ".lcr":"application/x-digitalloca" , ".lgh":"application/lgh" , ".lha":"application/octet-stream" , ".lml":"x-lml/x-lml" , ".lmlpack":"x-lml/x-lmlpack" , ".log":"text/plain" , ".lsf":"video/x-la-asf" , ".lsx":"video/x-la-asf" , ".lzh":"application/octet-stream" , ".m13":"application/x-msmediaview" , ".m14":"application/x-msmediaview" , ".m15":"audio/x-mod" , ".m3u":"audio/x-mpegurl" , ".m3url":"audio/x-mpegurl" , ".m4a":"audio/mp4a-latm" , ".m4b":"audio/mp4a-latm" , ".m4p":"audio/mp4a-latm" , ".m4u":"video/vnd.mpegurl" , ".m4v":"video/x-m4v" , ".ma1":"audio/ma1" , ".ma2":"audio/ma2" , ".ma3":"audio/ma3" , ".ma5":"audio/ma5" , ".man":"application/x-troff-man" , ".map":"magnus-internal/imagemap" , ".mbd":"application/mbedlet" , ".mct":"application/x-mascot" , ".mdb":"application/x-msaccess" , ".mdz":"audio/x-mod" , ".me":"application/x-troff-me" , ".mel":"text/x-vmel" , ".mht":"message/rfc822" , ".mhtml":"message/rfc822" , ".mi":"application/x-mif" , ".mid":"audio/mid" , ".midi":"audio/midi" , ".mif":"application/x-mif" , ".mil":"image/x-cals" , ".mio":"audio/x-mio" , ".mmf":"application/x-skt-lbs" , ".mng":"video/x-mng" , ".mny":"application/x-msmoney" , ".moc":"application/x-mocha" , ".mocha":"application/x-mocha" , ".mod":"audio/x-mod" , ".mof":"application/x-yumekara" , ".mol":"chemical/x-mdl-molfile" , ".mop":"chemical/x-mopac-input" , ".mov":"video/quicktime" , ".movie":"video/x-sgi-movie" , ".mp2":"video/mpeg" , ".mp3":"audio/mpeg" , ".mp4":"video/mp4" , ".mpa":"video/mpeg" , ".mpc":"application/vnd.mpohun.certificate" , ".mpe":"video/mpeg" , ".mpeg":"video/mpeg" , ".mpg":"video/mpeg" , ".mpg4":"video/mp4" , ".mpga":"audio/mpeg" , ".mpn":"application/vnd.mophun.application" , ".mpp":"application/vnd.ms-project" , ".mps":"application/x-mapserver" , ".mpv2":"video/mpeg" , ".mrl":"text/x-mrml" , ".mrm":"application/x-mrm" , ".ms":"application/x-troff-ms" , ".msg":"application/vnd.ms-outlook" , ".mts":"application/metastream" , ".mtx":"application/metastream" , ".mtz":"application/metastream" , ".mvb":"application/x-msmediaview" , ".mzv":"application/metastream" , ".nar":"application/zip" , ".nbmp":"image/nbmp" , ".nc":"application/x-netcdf" , ".ndb":"x-lml/x-ndb" , ".ndwn":"application/ndwn" , ".nif":"application/x-nif" , ".nmz":"application/x-scream" , ".nokia-op-logo":"image/vnd.nok-oplogo-color" , ".npx":"application/x-netfpx" , ".nsnd":"audio/nsnd" , ".nva":"application/x-neva1" , ".nws":"message/rfc822" , ".oda":"application/oda" , ".ogg":"audio/ogg" , ".oom":"application/x-AtlasMate-Plugin" , ".p10":"application/pkcs10" , ".p12":"application/x-pkcs12" , ".p7b":"application/x-pkcs7-certificates" , ".p7c":"application/x-pkcs7-mime" , ".p7m":"application/x-pkcs7-mime" , ".p7r":"application/x-pkcs7-certreqresp" , ".p7s":"application/x-pkcs7-signature" , ".pac":"audio/x-pac" , ".pae":"audio/x-epac" , ".pan":"application/x-pan" , ".pbm":"image/x-portable-bitmap" , ".pcx":"image/x-pcx" , ".pda":"image/x-pda" , ".pdb":"chemical/x-pdb" , ".pdf":"application/pdf" , ".pfr":"application/font-tdpfr" , ".pfx":"application/x-pkcs12" , ".pgm":"image/x-portable-graymap" , ".pict":"image/x-pict" , ".pko":"application/ynd.ms-pkipko" , ".pm":"application/x-perl" , ".pma":"application/x-perfmon" , ".pmc":"application/x-perfmon" , ".pmd":"application/x-pmd" , ".pml":"application/x-perfmon" , ".pmr":"application/x-perfmon" , ".pmw":"application/x-perfmon" , ".png":"image/png" , ".pnm":"image/x-portable-anymap" , ".pnz":"image/png" , ".pot,":"application/vnd.ms-powerpoint" , ".ppm":"image/x-portable-pixmap" , ".pps":"application/vnd.ms-powerpoint" , ".ppt":"application/vnd.ms-powerpoint" , ".pptx":"application/vnd.openxmlformats-officedocument.presentationml.presentation" , ".pqf":"application/x-cprplayer" , ".pqi":"application/cprplayer" , ".prc":"application/x-prc" , ".prf":"application/pics-rules" , ".prop":"text/plain" , ".proxy":"application/x-ns-proxy-autoconfig" , ".ps":"application/postscript" , ".ptlk":"application/listenup" , ".pub":"application/x-mspublisher" , ".pvx":"video/x-pv-pvx" , ".qcp":"audio/vnd.qcelp" , ".qt":"video/quicktime" , ".qti":"image/x-quicktime" , ".qtif":"image/x-quicktime" , ".r3t":"text/vnd.rn-realtext3d" , ".ra":"audio/x-pn-realaudio" , ".ram":"audio/x-pn-realaudio" , ".rar":"application/octet-stream" , ".ras":"image/x-cmu-raster" , ".rc":"text/plain" , ".rdf":"application/rdf+xml" , ".rf":"image/vnd.rn-realflash" , ".rgb":"image/x-rgb" , ".rlf":"application/x-richlink" , ".rm":"audio/x-pn-realaudio" , ".rmf":"audio/x-rmf" , ".rmi":"audio/mid" , ".rmm":"audio/x-pn-realaudio" , ".rmvb":"audio/x-pn-realaudio" , ".rnx":"application/vnd.rn-realplayer" , ".roff":"application/x-troff" , ".rp":"image/vnd.rn-realpix" , ".rpm":"audio/x-pn-realaudio-plugin" , ".rt":"text/vnd.rn-realtext" , ".rte":"x-lml/x-gps" , ".rtf":"application/rtf" , ".rtg":"application/metastream" , ".rtx":"text/richtext" , ".rv":"video/vnd.rn-realvideo" , ".rwc":"application/x-rogerwilco" , ".s3m":"audio/x-mod" , ".s3z":"audio/x-mod" , ".sca":"application/x-supercard" , ".scd":"application/x-msschedule" , ".sct":"text/scriptlet" , ".sdf":"application/e-score" , ".sea":"application/x-stuffit" , ".setpay":"application/set-payment-initiation" , ".setreg":"application/set-registration-initiation" , ".sgm":"text/x-sgml" , ".sgml":"text/x-sgml" , ".sh":"application/x-sh" , ".shar":"application/x-shar" , ".shtml":"magnus-internal/parsed-html" , ".shw":"application/presentations" , ".si6":"image/si6" , ".si7":"image/vnd.stiwap.sis" , ".si9":"image/vnd.lgtwap.sis" , ".sis":"application/vnd.symbian.install" , ".sit":"application/x-stuffit" , ".skd":"application/x-Koan" , ".skm":"application/x-Koan" , ".skp":"application/x-Koan" , ".skt":"application/x-Koan" , ".slc":"application/x-salsa" , ".smd":"audio/x-smd" , ".smi":"application/smil" , ".smil":"application/smil" , ".smp":"application/studiom" , ".smz":"audio/x-smd" , ".snd":"audio/basic" , ".spc":"application/x-pkcs7-certificates" , ".spl":"application/futuresplash" , ".spr":"application/x-sprite" , ".sprite":"application/x-sprite" , ".sdp":"application/sdp" , ".spt":"application/x-spt" , ".src":"application/x-wais-source" , ".sst":"application/vnd.ms-pkicertstore" , ".stk":"application/hyperstudio" , ".stl":"application/vnd.ms-pkistl" , ".stm":"text/html" , ".svg":"image/svg+xml" , ".sv4cpio":"application/x-sv4cpio" , ".sv4crc":"application/x-sv4crc" , ".svf":"image/vnd" , ".svg":"image/svg+xml" , ".svh":"image/svh" , ".svr":"x-world/x-svr" , ".swf":"application/x-shockwave-flash" , ".swfl":"application/x-shockwave-flash" , ".t":"application/x-troff" , ".tad":"application/octet-stream" , ".talk":"text/x-speech" , ".tar":"application/x-tar" , ".taz":"application/x-tar" , ".tbp":"application/x-timbuktu" , ".tbt":"application/x-timbuktu" , ".tcl":"application/x-tcl" , ".tex":"application/x-tex" , ".texi":"application/x-texinfo" , ".texinfo":"application/x-texinfo" , ".tgz":"application/x-compressed" , ".thm":"application/vnd.eri.thm" , ".tif":"image/tiff" , ".tiff":"image/tiff" , ".tki":"application/x-tkined" , ".tkined":"application/x-tkined" , ".toc":"application/toc" , ".toy":"image/toy" , ".tr":"application/x-troff" , ".trk":"x-lml/x-gps" , ".trm":"application/x-msterminal" , ".tsi":"audio/tsplayer" , ".tsp":"application/dsptype" , ".tsv":"text/tab-separated-values" , ".ttf":"application/octet-stream" , ".ttz":"application/t-time" , ".txt":"text/plain" , ".uls":"text/iuls" , ".ult":"audio/x-mod" , ".ustar":"application/x-ustar" , ".uu":"application/x-uuencode" , ".uue":"application/x-uuencode" , ".vcd":"application/x-cdlink" , ".vcf":"text/x-vcard" , ".vdo":"video/vdo" , ".vib":"audio/vib" , ".viv":"video/vivo" , ".vivo":"video/vivo" , ".vmd":"application/vocaltec-media-desc" , ".vmf":"application/vocaltec-media-file" , ".vmi":"application/x-dreamcast-vms-info" , ".vms":"application/x-dreamcast-vms" , ".vox":"audio/voxware" , ".vqe":"audio/x-twinvq-plugin" , ".vqf":"audio/x-twinvq" , ".vql":"audio/x-twinvq" , ".vre":"x-world/x-vream" , ".vrml":"x-world/x-vrml" , ".vrt":"x-world/x-vrt" , ".vrw":"x-world/x-vream" , ".vts":"workbook/formulaone" , ".wav":"audio/x-wav" , ".wax":"audio/x-ms-wax" , ".wbmp":"image/vnd.wap.wbmp" , ".wcm":"application/vnd.ms-works" , ".wdb":"application/vnd.ms-works" , ".web":"application/vnd.xara" , ".wi":"image/wavelet" , ".wis":"application/x-InstallShield" , ".wks":"application/vnd.ms-works" , ".wm":"video/x-ms-wm" , ".wma":"audio/x-ms-wma" , ".wmd":"application/x-ms-wmd" , ".wmf":"application/x-msmetafile" , ".wml":"text/vnd.wap.wml" , ".wmlc":"application/vnd.wap.wmlc" , ".wmls":"text/vnd.wap.wmlscript" , ".wmlsc":"application/vnd.wap.wmlscriptc" , ".wmlscript":"text/vnd.wap.wmlscript" , ".wmv":"audio/x-ms-wmv" , ".wmx":"video/x-ms-wmx" , ".wmz":"application/x-ms-wmz" , ".wpng":"image/x-up-wpng" , ".wps":"application/vnd.ms-works" , ".wpt":"x-lml/x-gps" , ".wri":"application/x-mswrite" , ".wrl":"x-world/x-vrml" , ".wrz":"x-world/x-vrml" , ".ws":"text/vnd.wap.wmlscript" , ".wsc":"application/vnd.wap.wmlscriptc" , ".wv":"video/wavelet" , ".wvx":"video/x-ms-wvx" , ".wxl":"application/x-wxl" , ".x-gzip":"application/x-gzip" , ".xaf":"x-world/x-vrml" , ".xar":"application/vnd.xara" , ".xbm":"image/x-xbitmap" , ".xdm":"application/x-xdma" , ".xdma":"application/x-xdma" , ".xdw":"application/vnd.fujixerox.docuworks" , ".xht":"application/xhtml+xml" , ".xhtm":"application/xhtml+xml" , ".xhtml":"application/xhtml+xml" , ".xla":"application/vnd.ms-excel" , ".xlc":"application/vnd.ms-excel" , ".xll":"application/x-excel" , ".xlm":"application/vnd.ms-excel" , ".xls":"application/vnd.ms-excel" , ".xlsx":"application/vnd.openxmlformats-officedocument.spreadsheetml.sheet" , ".xlt":"application/vnd.ms-excel" , ".xlw":"application/vnd.ms-excel" , ".xm":"audio/x-mod" , ".xml":"text/plain", ".xml":"application/xml", ".xmz":"audio/x-mod" , ".xof":"x-world/x-vrml" , ".xpi":"application/x-xpinstall" , ".xpm":"image/x-xpixmap" , ".xsit":"text/xml" , ".xsl":"text/xml" , ".xul":"text/xul" , ".xwd":"image/x-xwindowdump" , ".xyz":"chemical/x-pdb" , ".yz1":"application/x-yz1" , ".z":"application/x-compress" , ".zac":"application/x-zaurus-zac" , ".zip":"application/zip" , ".json":"application/json" }
三、模塊之間的調用
例子一:
首先我們在work directory中建立一個test文件夾,在其中新建兩個文件,bar.js,foo.js,文件內容分別如下:
bar.js:
1 console.log("我是bar");
foo.js:
1 var bar = require("./bar.js"); 2 var msg = "你好"; 3 var info = "呵呵"; 4
5 function showInfo(){ 6 console.log(info); 7 } 8
9 exports.msg = msg; 10 exports.info = info; 11 exports.showInfo = showInfo;
測試程序:
1 var foo = require("./test/foo.js");
2 console.log(foo.msg); 3 console.log(foo.info); 4 foo.showInfo();
在這個簡單的程序中,我們可以看到從主程序執行,首先引用foo.js在引用的時候就執行該js的代碼,而執行foo的時候第一句又是一個require,這個時候就會找到bar.js來執行,結果就是輸出一串字符串,然后就沒有了,借着主程序開始執行第二行,因為foo中已經暴露了相應的接口,所以可以訪問其中的對象和方法,所以輸出相應的內容。在這里我們要注意,1、require的過程其實也是一種執行的過程;2、模塊之間通過exports來暴露接口,並且通過require來使用,這就給我們編程帶來了極大的方便。程序運行的結果是:
例子二:
暴露一個類:
People.js:
1 function People(name,sex,age){ 2 this.name = name; 3 this.sex = sex; 4 this.age = age; 5 } 6 People.prototype = { 7 sayHello : function(){ 8 console.log(this.name + " "+this.sex +" " + this.age); 9 } 10 } 11 //此時,People就被視為構造函數,可以用new來實例化了。
12 module.exports = People;
主程序:
1 var People = require("./test/People.js"); 2 var xiaoming = new People("小明","男","12"); 3 xiaoming.sayHello(); 4 console.log(xiaoming.age); 5 console.log(xiaoming.sex);
這里注意暴露一個類使用的是module.exports,通過把類賦值給該變量既可以在主程序中生成對象了,這點非常方便。執行結果為:
例子三:
在node.js中如果將js文件放到node_modules文件夾下,那么我們就可以不用寫路徑名來直接引用,因為系統會自己找到該文件夾並且從中找到我們對應的文件。
我們在主程序中,用下面的代碼來執行,可以看到輸出的結果為:
1 var foo = require("foo.js"); //沒有寫./
2 console.log(foo.msg);
用var foo = require("bar.js"); //沒有寫./來測試結果為:
例子四:文件夾中引用,如下圖所示,在node_modules中建立了一個文件夾,在文件夾中用了package.json來定義該文件夾下的執行文件的入口是app.js,因此我們就可以在主程序中直接調用該文件夾來執行相應的文件了,執行結果如下:
主程序:
1 var bar = require("bar"); //在引用一個文件夾
2 console.log(bar.msg);
例子五:
同樣的,在node.js世界中,因為有npm(node.js package manager)的存在,我們可以使用別人的代碼,在命令行中我們可以直接使用npm install 包名來從網上下載相應的包到本地的node_modules中使用,也可以使用npm install命令來自己配置package.json文件從而自行下載相應的文件,這兩種方法都是有效可行的!
1 var sd = require("silly-datetime"); 2 var ttt = sd.format(new Date(), 'YYYYMMDDHHmm'); 3 console.log(ttt);
四、路由的剝離
首先我們看一個程序:
1 var http = require("http"); 2 var router = require("./router.js"); 3
4 //創建服務器
5 var server = http.createServer(function(req,res){ 6 if(req.url == "/"){ 7 router.showIndex(req,res); 8 }else if(req.url.substr(0,9) == "/student/"){ 9 router.showStudent(req,res); 10 }else{ 11 router.show404(req,res); 12 } 13 }); 14 server.listen(3100,"127.0.0.1");
router.js:
1 exports.showIndex = showIndex; 2 exports.showStudent = showStudent; 3 exports.show404 = show404; 4
5 function showIndex(req,res){ 6 res.writeHead(200,{"Content-Type":"text/html;charset=UTF8"}); 7 res.end("我是首頁"); 8 } 9
10 function showStudent(req,res){ 11 var id = req.url.substr(9,6); 12 res.writeHead(200,{"Content-Type":"text/html;charset=UTF8"}); 13 res.end("我是學生頁面" + id); 14 } 15
16 function show404(req,res){ 17 res.writeHead(404,{"Content-Type":"text/html;charset=UTF8"}); 18 res.end("404"); 19 }
在這個程序里,我們將路由的具體處理過程拋給了相應的處理程序,然后用模塊調用的方式來完成了導航功能,大大的簡化了我們的代碼,增加了代碼的清晰度。
五、post請求提交
首先我們新建一個html,包含有表單,我們通過表單來提交數據。

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Document</title>
</head>
<body>
<form action="dopost" method="post" enctype="multipart/form-data">
<p> 姓名 : <input type="text" name="name">
</p>
<p> 性別 : <input type="radio" name="sex" value="男">男 <input type="radio" name="sex" value="女">女 </p>
<p> 愛好: <input type="checkbox" name="hobby" value="睡覺" />睡覺 <input type="checkbox" name="hobby" value="吃飯" />吃飯 <input type="checkbox" name="hobby" value="足球" />足球 </p>
<p> 圖片: <input type="file" name="tupian" />
</p>
<p>
<input type="submit" />
</p>
</form>
</body>
</html>
服務器代碼:
1 var http = require("http"); 2 var querystring = require("querystring"); 3 //創建服務器
4 var server = http.createServer(function(req,res){ 5 //如果你的訪問地址是這個,並且請求類型是post
6 if(req.url == "/dopost" && req.method.toLowerCase() == "post"){ 7 var urlstr=""; 8 req.addListener("data",function(postdata){ 9 urlstr+=postdata; //接收到的表單數據字符串
10 var jsondata = querystring.parse(urlstr); //轉換成json對象
11 var decodedata = decodeURIComponent(urlstr); //對表單數據進行解碼
12 console.log("原數據(加密數據): "+urlstr); 13 console.log("json數據(轉換成對象): "); 14 console.log(jsondata); 15 console.log("解碼數據: "+decodedata); 16 urlstr = decodedata; 17 }); 18 req.addListener("end",function(){ 19 res.writeHead(200,{"Content-Type":"text/plain; charset=utf-8"}); 20 res.write(urlstr); 21 res.end(); 22 }); 23 } 24 }); 25 server.listen(3100,"127.0.0.1");
運行結果:
上面的代碼,是網上廣為流傳的代碼,我想很多人並沒有實踐過,而是只從書上抄過來的,豈不知在現在的編譯器中早就行不通了,為什么呢,一個事情的發生必定有其原因,我們本來是想得到含有鍵值對的有效地json數據,可是我們現在得到了什么,只是一些描述符下面包含的我們輸入的有效信息,為什么會這樣呢?!這個問題花費了我很長時間,總算找到了原因,其實我們的思路並沒錯,只不過瀏覽器傳遞過來的數據,對於每一個字段都做了描述,正如我們看到的這些不知道什么意思的數字,還有回車符等,傳統的方法是解決不了的,我在網上搜了很多解決辦法,最后發現這個東西在現在的node.js版本中就是這樣的,我們的方法並沒錯,通過異步的方法,從事件中不斷地累加我們的數據,data事件讓我們收到所有的數據,而數據收完之后就會觸發end方法讓我們對數據進行處理,因此在這里我們不應該只是簡單的接收到數據,而應該對那么長的一段字符串進行解析,也就是返回瀏覽器的那些數據,這些字段的修飾是很有規律的,因此我們可以使用正則表達式或者字符串的遍歷的方法(數據清洗)從這些無序的數據中抽取出我們需要的信息,然后構成鍵值對並且返回,這是唯一正確的方法,在原生的接收數據的方法中這是非常可取的,不過代碼和工作量將大大的激增,那么有沒有更好的解決辦法呢,因為生活中我們經常遇到這樣的例子,比如說我們申請國獎國勵的時候,經常需要在網上填寫信息,然后post過去,如果這個問題解決不了,除非我們不使用nodejs了,但是也會遇到其他的問題,因此,在node.js中不只我們遇到這樣的問題,因此就會有很多人有相應的解決辦法,比如說formidable這個npm共享資源的有機組成部分就是解決這個問題的,使用也非常的簡單!
方法二:formidable
首先我們download這個module:
然后我們運行服務器:
1 var http = require("http"); 2 var formidable = require('formidable'); 3 var util = require("util"); 4 var server = http.createServer(function(req,res){ 5 if(req.url == "/dopost" && req.method.toLowerCase() == "post"){ 6 //Creates a new incoming form.
7 var form = new formidable.IncomingForm(); 8 //設置文件上傳存放地址
9 form.uploadDir = "./uploads"; 10 //執行里面的回調函數的時候,表單已經全部接收完畢了。
11 form.parse(req, function(err, fields, files) { 12 if(err){ 13 throw err; 14 } 15 console.log(fields); 16 console.log(files); 17 console.log(util.inspect({fields: fields, files: files})); 18 //所有的文本域、單選框,都在fields存放;
19 //所有的文件域,files
20 res.writeHead(200, {'content-type': 'text/plain'}); 21 res.end("成功"); 22 }); 23 } 24 }); 25
26 server.listen(3100,"127.0.0.1");
運行結果:
更無限強大的是,我們竟然得到了如此詳細的信息,json數據也早就有了,而且我們還可以上傳文件,比如說圖片,文檔等,這是多么厲害的一種技術呀,從這里可以看到我們從開源的社區找到別人用心寫好的具有很強的魯棒性的產品並且拿來為自己所用是多么的重要和有意義,從另一方面也說明了資源的共享是多么的重要!
上傳一張圖片看看:
添加擴展名之后:
到這里為止,我們可以看到formidable的強大之處了,只是美中不足的是,上傳的圖片沒有擴展名,並且是自動生成的文件名,因此我們下面可以對文件進行改名,這樣我們就可以實現更好的效果和用戶體驗了!!!
代碼如下:
1 var http = require("http"); 2 var formidable = require('formidable'); 3 var util = require("util"); 4 var fs = require("fs"); 5 var sd = require("silly-datetime"); 6 var path = require("path"); 7 var server = http.createServer(function(req,res){ 8 if(req.url == "/dopost" && req.method.toLowerCase() == "post"){ 9 //Creates a new incoming form.
10 var form = new formidable.IncomingForm(); 11 //設置文件上傳存放地址
12 form.uploadDir = "./uploads"; 13 //執行里面的回調函數的時候,表單已經全部接收完畢了。
14 form.parse(req, function(err, fields, files) { 15 if(err){ 16 throw err; 17 } 18 //console.log(util.inspect({fields: fields, files: files}));
19 //時間,使用第三方模塊,silly-datetime
20 var ttt = sd.format(new Date(), 'YYYYMMDDHHmmss'); 21 var ran = parseInt(Math.random() * 89999 + 10000); 22 var extname = path.extname(files.tupian.name); 23 //執行改名
24 var oldpath = __dirname + "/" + files.tupian.path; 25 //新的路徑由三個部分組成:時間戳、隨機數、拓展名
26 var newpath = __dirname + "/uploads/" + ttt + ran + extname; 27
28 //改名
29 fs.rename(oldpath,newpath,function(err){ 30 if(err){ 31 throw Error("改名失敗"); 32 } 33 res.writeHead(200, {'content-type': 'text/plain'}); 34 res.end("成功"); 35 }); 36 }); 37 }else if(req.url == "/"){ 38 //呈遞form.html頁面
39 fs.readFile("./form.html",function(err,data){ 40 res.writeHead(200, {'content-type': 'text/html'}); 41 res.end(data); 42 }) 43 }else{ 44 res.writeHead(404, {'content-type': 'text/html'}); 45 res.end("404"); 46 } 47 }); 48 server.listen(3100,"127.0.0.1");
運行結果可知,我們的程序成功的將圖片名改成了自己想要的格式,並且基本上不會重復,適合高並發訪問!!!
六、模板引擎ejs
最后讓我們看一下模板引擎,首先我們還是下載ejs:
然后是代碼:
1 var ejs = require("ejs"); 2 //模板
3 var string = "好高興啊,今天我買了iphone<%= a %>s"; 4 //數據
5 var data = { 6 a : 8
7 }; 8 //數據綁定
9 var html = ejs.render(string, data); 10 //輸出
11 console.log(html);
結果:可以看到我們成功的實現了綁定!根據這一特性我們可以實現更好的效果。
高級版:
1 var ejs = require("ejs"); 2 var fs = require("fs"); 3 var http = require("http"); 4 var server = http.createServer(function(req,res){ 5 fs.readFile("./views/index.ejs",function(err,data){ 6 //綁定模板
7 var template = data.toString(); 8 var dictionary = { 9 a:7, 10 news : [ 11 {"title":"第一條新聞","count":10}, 12 {"title":"第二條新聞","count":20}, 13 {"title":"第三條新聞","count":30} 14 ] 15 }; 16 var html = ejs.render(template,dictionary); 17 //顯示
18 res.writeHead(200,{"Content-Type":"text/html;charset=UTF8"}); 19 res.end(html); 20 }); 21 }); 22
23 server.listen(3100,"127.0.0.1");
index.ejs:
1 <!doctype html>
2 <html lang="en">
3 <head>
4 <meta charset="UTF-8">
5 <title></title>
6 </head>
7 <body>
8 <h1>好高興啊,今天我買了一個iphone<%= a %>s</h1>
9 <ul>
10 <%
11 for(var i = 0 ; i < news.length ; i++){ 12 if(news[i].count > 15){ 13 %>
14 <li><%= news[i].title %></li>
15 <%
16 } 17 } 18 %>
19 </ul>
20 </body>
21 </html>
運行結果:為我們編寫大型程序奠定了基礎!!!
七、總結
呼,好長的一篇文章呀,中間斷斷續續,加上其他的事情,一直寫了一個星期了,能寫完真的不容易,里面的很多技術,都是最底層的東西,這樣由淺入深的學習才能循序漸進,其實到了這個地方,我們完全可以放手去寫一些大型的工程了,因為我們已經具備了良好的基礎,有了B/S之間通信的基礎,這些都是我們可以仰仗的資本,最重要的是我們可以使用npm這個強大到令人望其項背的神器,我們也可以在上面投放屬於我們自己的模塊,造福於其他人!!!如果您看到了這個地方,那您一定是一個比較勤奮的人,並且想學一些東西,對於寫文章,我一直都是處於一種興趣和熱情,肯定有些許的疏漏之處,還請多多指出,希望我的文章可以幫助到那些樂於學習,樂於奉獻的人,謝謝!!!!!!