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这个强大到令人望其项背的神器,我们也可以在上面投放属于我们自己的模块,造福于其他人!!!如果您看到了这个地方,那您一定是一个比较勤奋的人,并且想学一些东西,对于写文章,我一直都是处于一种兴趣和热情,肯定有些许的疏漏之处,还请多多指出,希望我的文章可以帮助到那些乐于学习,乐于奉献的人,谢谢!!!!!!