一、創(chuàng )建http服務(wù)器
node.js的web程序不用放入web容器中運行,可以自己創(chuàng )建一個(gè)http服務(wù)器運行程序。需要使用http核心模塊。
1 //創(chuàng )建一個(gè)http服務(wù)器 2 const http=require('http'); 3 //創(chuàng )建一個(gè)http服務(wù)器 4 const server=http.createServer((req,res)=>{ 5 //設置響應頭 6 res.writeHead(200, {'Content-Type': 'text/html;charset=utf8'}); 7 //通知服務(wù)器,所有響應頭和響應主體都已被發(fā)送 8 res.end("hello world"); 9 });10 server.listen('8080',"127.0.0.1",(err)=>{11 if(err)12 throw err;13 console.log("服務(wù)器啟動(dòng)成功");14 })可以在瀏覽器通過(guò)http://localhost:8080訪(fǎng)問(wèn)服務(wù)器。
二、訪(fǎng)問(wèn)服務(wù)器上的靜態(tài)頁(yè)面
1 //創(chuàng )建一個(gè)http服務(wù)器 2 const http = require('http'); 3 const fs = require('fs'); 4 //創(chuàng )建一個(gè)http服務(wù)器 5 const server = http.createServer((req, res) => { 6 if (req.url == "/yuan") { 7 //訪(fǎng)問(wèn)頁(yè)面yuan.html 8 fs.readFile('./yuan.html', "utf8", (err, data) => { 9 if (err)10 throw err;11 //設置響應頭12 res.writeHead(200, { 'Content-Type': 'text/html;charset=utf8'});13 //通知服務(wù)器,所有響應頭和響應主體都已被發(fā)送14 res.end(data);15 });16 } else if (req.url == '/fang') {17 //訪(fǎng)問(wèn)頁(yè)面fang.html18 fs.readFile('./fang.html', "utf8", (err, data) => {19 if (err)20 throw err;21 //設置響應頭22 res.writeHead(200, { 'Content-Type': 'text/html', 'charset': "utf8" });23 //通知服務(wù)器,所有響應頭和響應主體都已被發(fā)送24 res.end(data);25 });26 }27 else if (req.url == "/tupian") {28 //為圖片配置路由29 fs.readFile('./node.png', (err, data) => {30 if (err)31 throw err;32 //設置響應頭33 //通知服務(wù)器,所有響應頭和響應主體都已被發(fā)送34 res.end(data);35 });36 }37 else {38 //加載含有圖片的頁(yè)面要配置多個(gè)路由39 fs.readFile('./tupian.html', (err, data) => {40 if (err)41 throw err;42 //設置響應頭43 //通知服務(wù)器,所有響應頭和響應主體都已被發(fā)送44 res.end(data);45 });46 }47 });48 server.listen('8080', "127.0.0.1", (err) => {49 if (err)50 throw err;51 console.log("服務(wù)器啟動(dòng)成功");52 })設置四個(gè)簡(jiǎn)單的路由,獲取服務(wù)器上的靜態(tài)頁(yè)面。
三、閉包和鏈式調用
使用下面的代碼讀取./album文件夾下的所有文件,把其中的文件夾放入dir數組中。然后遍歷dir數組。./album下的文件如下:

1 const fs = require('fs'); 2 var dir=[]; 3 fs.readdir('./album',(err,files)=>{ 4 for(var i=0;i<files.length;i++){ 5 var thefile=files[i]; 6 fs.stat(`./album/${thefile}`,(err,state)=>{ 7 if(state.isDirectory()) 8 dir.push(thefile); 9 console.log(dir);10 });11 }12 })控制臺打印的結果如下:

分析: fs.readdir()的回調函數中定義了變量thefile,回調函數在調用的時(shí)候會(huì )把變量thefile綁定到相關(guān)的對象上?;卣{函數中又定義了回調函數,所以嵌套的回調函數會(huì )把這個(gè)對象添加到自己的作用域上。但是fs.readdir()調用時(shí)循環(huán)會(huì )改變thefile的值,所以回調函數的作用域連上的thedfile指向最后一個(gè)文件名?! ?/strong>
fs.stat(`./album/${thefile}`,callback)中我們傳入的實(shí)參是對應的每一個(gè)的文件名。
解決方法1:利用閉包讓thefile變量不共享。
1 const fs = require('fs'); 2 var dir=[]; 3 fs.readdir('./album',(err,files)=>{ 4 for(var i=0;i<files.length;i++){ 5 var thefile=files[i]; 6 (function (f){ 7 fs.stat(`./album/${f}`,(err,state)=>{ 8 if(state.isDirectory()) 9 dir.push(f);10 console.log(dir);11 });12 }(thefile)) 13 }14 })

解決方法2:每次只讓事件隊列中有一個(gè)fs.stat()函數在執行。
1 const fs = require('fs'); 2 var dir=[]; 3 fs.readdir('./album',(err,files)=>{ 4 (function itera(f){ 5 //結束遞歸 6 if(f===files.length){ 7 console.log(dir); 8 return; 9 } 10 fs.stat(`./album/${files[f]}`,(err,state)=>{ 11 if(state.isDirectory())12 dir.push(files[f]);13 console.l14 og(`./album/${files[f]}`);15 itera(++f);16 });17 }(0)) 18 })

五、自己實(shí)現靜態(tài)服務(wù)
1 //用node提供靜態(tài)服務(wù) 2 const http = require('http'); 3 const fs = require('fs'); 4 const url = require('url'); 5 const path = require('path'); 6 const server = http.createServer((req, res) => { 7 //獲取要訪(fǎng)問(wèn)的文件路徑 8 let requrl = url.parse(req.url).pathname; 9 //拼合成絕對路徑10 let dirpath = path.join(__dirname, 'static', requrl);11 //讀取當前路徑下的文件12 fs.readFile(dirpath, (err, data) => {13 //當前文件不存在14 if (err) {15 let p404 = path.join(__dirname, 'static/404.html');16 fs.readFile(p404, (err, data) => {17 if (err)18 throw err;19 res.writeHead(404, { 'Content-Type': `text/html;charset=utf8` });20 res.end(data)21 });22 return;23 }24 //文件存在25 //獲取文件的后綴名26 let ext = path.extname(requrl);27 //異步的方式獲取響應頭28 getMime(ext, (mime) => {29 res.writeHead(200, { 'Content-Type': `${mime};charset=utf8` });30 res.end(data);31 });32 });33 });34 server.listen('8080', 'localhost', (err) => {35 if (err)36 throw err;37 console.log("服務(wù)器成功啟動(dòng)!");38 });39 //根據文件的類(lèi)型給出對應的mime類(lèi)型40 function getMime(extname, callback) {41 let file = path.join(__dirname, 'mime.json');42 fs.readFile(file, (err, data) => {43 if (err)44 throw err;45 data = JSON.parse(data);46 let mime = data[extname] || "text/plain";47 callback(mime);48 })49 }當服務(wù)器啟動(dòng)時(shí),放在static文件下的問(wèn)價(jià)可以被直接訪(fǎng)問(wèn)。
六、post請求和get請求
1 //post請求 2 const http = require('http'); 3 const fs = require('fs'); 4 const querystring=require('querystring'); 5 http.createServer((req, res) => {
//讀取服務(wù)器上的靜態(tài)頁(yè)面 6 if (req.url == '/') { 7 fs.readFile('./form.html', (err, data) => { 8 if (err) 9 throw err;10 res.writeHead(200, { 'Content-Type': `text/html;charset=utf8` });11 res.end(data);12 })13 }
//接受post請求14 else if (req.url = "/dopost" && req.method.toLocaleLowerCase() == 'post') {15 let data = '';16 req.addListener('data', (chunk) => {17 data += chunk;18 });19 req.addListener('end', () => {
//打印接受的數據20 console.log(data);
//將數據轉換成字符串21 let dataObj=querystring.parse(data);22 console.log(dataObj.user);23 }) 24 res.writeHead(200, { 'Content-Type': `text/html;charset=utf8` });25 res.end('success');26 }27 else {28 res.writeHead(200, { 'Content-Type': `text/html;charset=utf8` });29 res.end('404');30 }31 }).listen('8080', 'localhost');
1 //get請求 2 const http=require('http'); 3 const url=require('url'); 4 //創(chuàng )建一個(gè)服務(wù)器 5 http.createServer((req,res)=>{ 6 //解析接受到url 7 //輸入http://localhost:8080/lijunjie.hml?name=123 8 let urlObj=url.parse(req.url); 9 //輸出name=12310 console.log(urlObj.query);11 res.end('請求成功');12 }).listen(8080,'localhost');
七、ejs模板引擎

首先需要通過(guò)npm安裝ejs模塊。創(chuàng )建index.ejs文件。
1 <!DOCTYPE html> 2 <html lang="en"> 3 4 <head> 5 <meta charset="UTF-8"> 6 <title>Document</title> 7 </head> 8 9 <body>10 <p> 我買(mǎi)了一個(gè)小米11 <%=a%>12 </p>13 <% for(var i=0;i<news.length;i++){%>14 <li>15 <%=news[i]%>16 </li>17 <%}%>18 </body>bind.js文件
1 //創(chuàng )建一個(gè)http服務(wù)器 2 const http = require('http'); 3 const fs = require('fs'); 4 const ejs=require('ejs'); 5 //創(chuàng )建一個(gè)http服務(wù)器 6 const server = http.createServer((req, res) => { 7 //讀取模板 8 fs.readFile('./index.ejs', (err, data) => { 9 //接受模板10 let template = data.toString();11 //數據12 let datas = { a: 3, news: ['adsada', 'xiaomi'] };13 let html=ejs.render(template,datas);14 res.end(html);15 })16 17 });18 server.listen('8080', "127.0.0.1", (err) => {19 if (err)20 throw err;21 console.log("服務(wù)器啟動(dòng)成功");22 })
聯(lián)系客服