實(shí)驗(yàn)操作
新建一個(gè)app.js文件
const http = require('http');
const fs = require('fs');
const path = require('path');
const url = require('url');
let common = require('./modules/common');
http.createServer((req, res) => {
let pathName = req.url; // 獲取到請(qǐng)求的url
pathName = url.parse(pathName).pathname; // 使用url內(nèi)置模塊獲取路徑名
pathName = pathName !== '/' ? pathName : '/index.html' // 獲取到/就默認(rèn)為/index.html
let extname = path.extname(pathName); // 使用內(nèi)部模塊path獲取文件后綴名
if (pathName !== "/favicon.ico") {
fs.readFile(path.join(__dirname, '../static') + pathName, (err, data) => {
// 使用path根據(jù)當(dāng)前路勁獲得讀取文件的相對(duì)路徑
if (err) {
res.writeHead(404, {
"Content-Type": "text/html;charset=UTF-8"
});
res.end('404這個(gè)網(wǎng)頁不存在');
}
let mime = common.getMime(extname); // 使用自定義模塊根據(jù)后綴名獲取Content-Type的值
res.writeHead(200, {
"Content-Type": "" + mime + ";charset=UTF-8"
});
res.end(data);
})
}
}).listen(3000);
console.log("Server runing at http://127.0.0.1:3000");
在app.js目錄下新建/modules/common.js
exports.getMime = function (extname) {
switch (extname) {
case '.html':
return 'text/html';
case '.css':
return 'text/css';
case '.js':
return 'text/javascript';
default:
return 'text/html';
}
}
以上的common.js中的getMime 函數(shù)所列舉的類并不完整,引入完整的對(duì)應(yīng)關(guān)系需要使用一個(gè)json文件:https://github.com/wxyzcctv/node-demo-sd10/blob/main/data/mime.json
該json文件放在/data/mime.json
在common.js文件中使用添加如下代碼:
const fs = require('fs');
const path = require('path');
// 方式一
exports.getFileMime = function (extname) {
return new Promise((resolve, reject) => {
fs.readFile(path.join(__dirname, '../data/mime.json'), (err, data) => {
if (err) {
console.log(err);
reject(err)
return err;
}
let mime = JSON.parse(data.toString());
resolve(mime[extname])
})
})
}
// 方式二:
exports.getFileMime = function (extname) {
let data = fs.readFileSync(path.join(__dirname, '../data/mime.json'));
let mime = JSON.parse(data.toString());
return mime[extname]
}
common.js中使用方式一菌湃,此時(shí)app.js中代碼為
const http = require('http');
const fs = require('fs');
const path = require('path');
const url = require('url');
let common = require('./modules/common');
http.createServer((req, res) => {
let pathName = req.url; // 獲取到請(qǐng)求的url
pathName = url.parse(pathName).pathname; // 使用url內(nèi)置模塊獲取路徑名
pathName = pathName !== '/' ? pathName : '/index.html' // 獲取到/就默認(rèn)為/index.html
let extname = path.extname(pathName); // 使用內(nèi)容模塊path獲取文件后綴名
if (pathName !== "/favicon.ico") {
fs.readFile(path.join(__dirname, './static') + pathName, async (err, data) => {
// 使用path根據(jù)當(dāng)前路勁獲得讀取文件的相對(duì)路徑
if (err) {
res.writeHead(404, {
"Content-Type": "text/html;charset=UTF-8"
});
res.end('404這個(gè)網(wǎng)頁不存在');
}
// let mime = common.getMime(extname); // 使用自定義模塊根據(jù)后綴名獲取Content-Type的值
let mime = await common.getFileMime(extname); // 使用自定義模塊根據(jù)后綴名獲取Content-Type的值
res.writeHead(200, {
"Content-Type": "" + mime + ";charset=UTF-8"
});
res.end(data);
})
}
}).listen(3000);
console.log("Server runing at http://127.0.0.1:3000");
common.js中使用方式二就在app.js中就去掉async和await
封裝靜態(tài)web服務(wù)
新建/module/routers.js
const fs = require('fs');
const path = require('path');
const url = require('url');
let getFileMime = function (extraname) {
let data = fs.readFileSync(path.join(__dirname,'../data/mime.json')); // 同步操作
data = JSON.parse(data.toString())
return data[extraname]
}
exports.static = function(req,res,staticPath){
let pathName = req.url; // 獲取到請(qǐng)求的url
pathName = url.parse(pathName).pathname; // 使用url內(nèi)置模塊獲取路徑名
pathName = pathName !== '/' ? pathName : '/index.html' // 獲取到/就默認(rèn)為/index.html
let extname = path.extname(pathName); // 使用內(nèi)容模塊path獲取文件后綴名
if (pathName !== "/favicon.ico") {
try {
let data = fs.readFileSync('../' + staticPath + pathName); // 同步操作
if(data){
let mime = getFileMime(extname); // 使用自定義模塊根據(jù)后綴名獲取Content-Type的值
res.writeHead(200, {
"Content-Type": "" + mime + ";charset=UTF-8"
});
res.end(data);
}
} catch (error) {
}
}
}
在app.js文件中
const http = require('http');
const url = require('url');
let routers = require('./modules/routers.js');
http.createServer((req, res) => {
routers.static(req, res, 'static');
// 增加路由
let pathName = url.parse(req.url).pathname;
if(pathName === '/login'){
res.writeHead(200, {
"Content-Type": "text/html;charset=UTF-8"
});
res.end('訪問登錄頁面');
} else if(pathName === '/register'){
res.writeHead(200, {
"Content-Type": "text/html;charset=UTF-8"
});
res.end('訪問登錄頁面');
} else if(pathName === '/admin'){
res.writeHead(200, {
"Content-Type": "text/html;charset=UTF-8"
});
res.end('訪問管理頁面');
}
}).listen(3000);
console.log("Server runing at http://127.0.0.1:3000");
使用ejs
EJS 常用標(biāo)簽
<% %>流程控制標(biāo)簽
<%= %>輸出標(biāo)簽(原文輸出 HTML 標(biāo)簽)
<%- %>輸出標(biāo)簽(HTML 會(huì)被瀏覽器解析)
<a href="<%= url %>"><img src="<%= imageURL %>" alt=""></a><ul>
<ul> <% for(var i = 0 ; i < news.length ; i++){ %> <li><%= news[i] %></li> <% } %> </ul>
先安裝ejs: npm install ejs --save
新建views/login.ejs文件
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<h2>這是一個(gè)登錄頁面</h2>
<h3>
<%=msg%>
</h3>
<br>
<ul>
<%for(let i=0; i < list.length; i++){ %>
<li>
<%=list[i].title%>
</li>
<%}%>
</ul>
</body>
</html>
然后在app.js中使用ejs
const http = require('http');
const url = require('url');
let routes = require('./modules/routes');
const ejs = require('ejs')
http.createServer((req, res) => {
routes.static(req, res, 'static')
let pathName = url.parse(req.url).pathname;
if (pathName === '/login') {
let msg = "這是數(shù)據(jù)庫傳回的數(shù)據(jù)";
let list = [
{ title: '標(biāo)題1' },
{ title: '標(biāo)題2' },
{ title: '標(biāo)題3' },
{ title: '標(biāo)題4' },
{ title: '標(biāo)題5' },
]
ejs.renderFile('./views/login.ejs', { msg: msg, list: list }, (err, data) => {
if (err) {
console.log(err);
return;
}
res.writeHead(200, {
"Content-Type": "text/html;charset=UTF-8"
});
res.end(data)
})
} else if (pathName === '/register') {
res.writeHead(200, {
"Content-Type": "text/html;charset=UTF-8"
});
res.end('正在操作注冊(cè)頁面')
} else if (pathName === '/admin') {
res.writeHead(200, {
"Content-Type": "text/html;charset=UTF-8"
});
res.end('處理之后的業(yè)務(wù)邏輯')
} else {
// res.writeHead(404, {
// "Content-Type": "text/html;charset=UTF-8"
// });
// res.end('404頁面不存在')
}
}).listen(3000);
console.log("Server runing at http://127.0.0.1:3000");
獲取請(qǐng)求方法名
req.method;
GET請(qǐng)求
獲取 GET 傳值:
var urlinfo=url.parse(req.url,true).query;
在app.js中添加/news的路由问拘,并在瀏覽器的地址欄中輸入http://localhost:3000/news?id=1&page=2
實(shí)現(xiàn)get請(qǐng)求,
const http = require('http');
const url = require('url');
let routes = require('./modules/routes');
const ejs = require('ejs')
http.createServer((req, res) => {
routes.static(req, res, 'static')
let pathName = url.parse(req.url).pathname;
if (pathName === '/login') {
res.writeHead(200, {
"Content-Type": "text/html;charset=UTF-8"
});
res.end('這是一個(gè)登錄頁面')
} else if (pathName === '/register') {
res.writeHead(200, {
"Content-Type": "text/html;charset=UTF-8"
});
res.end('正在操作注冊(cè)頁面')
} else if (pathName === '/admin') {
res.writeHead(200, {
"Content-Type": "text/html;charset=UTF-8"
});
res.end('處理之后的業(yè)務(wù)邏輯')
} else if (pathName === '/news') {
// 獲取請(qǐng)求方法名
console.log(req.method);
let params = url.parse(req.url, true).query;
console.log(params.page);
res.writeHead(200, {
"Content-Type": "text/html;charset=UTF-8"
});
res.end('獲取get請(qǐng)求成功')
}
}).listen(3000);
console.log("Server runing at http://127.0.0.1:3000");
POST請(qǐng)求
獲取 POST 傳值:
var postData = '';
// 數(shù)據(jù)塊接收中
req.on('data', function (postDataChunk) {
postData += postDataChunk;
});
// 數(shù)據(jù)接收完畢,執(zhí)行回調(diào)函數(shù)
req.on('end', function () {
try {
postData = JSON.parse(postData);
} catch (e) {}
req.query = postData;
console.log(querystring.parse(postData));
});
新建views/form.ejs
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<form action="/doLogin" method="post">
用戶名:<input type="text" name="userName" value="admin">
<br>
<br>
密 碼:<input type="password" name="password" value="123456">
<br>
<br>
<input type="submit" value="提交">
</form>
</body>
</html>
在app.js中修改logoin路由中的內(nèi)容并以及新增一個(gè)/doLogin路由
if (pathName === '/login') {
ejs.renderFile('./views/form.ejs', (err, data) => {
if (err) {
console.log(err);
return err;
}
res.writeHead(200, {
"Content-Type": "text/html;charset=UTF-8"
});
res.end(data)
})
} else if (pathName === '/doLogin') {
let postStr = '';
req.on('data', (chunk) => {
postStr += chunk
})
req.on('end', () => {
console.log(postStr);
res.end(postStr)
})
}
封裝路由
在/modules/routers.js文件中
使用app對(duì)象封裝靜態(tài)方法和路由訪問
const fs = require('fs');
const path = require('path');
const url = require('url');
const ejs = require('ejs');
let getFileMime = function (extraname) {
let data = fs.readFileSync(path.join(__dirname,'../data/mime.json'));
data = JSON.parse(data.toString())
return data[extraname]
}
let app = {
static: function(req,res,staticPath){
let pathName = req.url; // 獲取到請(qǐng)求的url
pathName = url.parse(pathName).pathname; // 使用url內(nèi)置模塊獲取路徑名
pathName = pathName !== '/' ? pathName : '/index.html' // 獲取到/就默認(rèn)為/index.html
let extname = path.extname(pathName); // 使用內(nèi)容模塊path獲取文件后綴名
if (pathName !== "/favicon.ico") {
try {
let data = fs.readFileSync('./' + staticPath + pathName);
if(data){
let mime = getFileMime(extname); // 使用自定義模塊根據(jù)后綴名獲取Content-Type的值
res.writeHead(200, {
"Content-Type": "" + mime + ";charset=UTF-8"
});
res.end(data);
}
} catch (error) {
}
}
},
// 該部分是路由封裝
// <-----------
login: (req,res)=>{
// 處理登錄路由的操作
ejs.renderFile(path.join(__dirname,'../views/form.ejs'),(err,data)=>{
if(err){
console.log(err);
return err;
}
res.writeHead(200, {
"Content-Type": "text/html;charset=UTF-8"
});
res.end(data);
})
},
register: (req,res)=>{
// 處理注冊(cè)路由的操作
res.writeHead(200, {
"Content-Type": "text/html;charset=UTF-8"
});
res.end('訪問注冊(cè)頁面');
},
admin: (req,res)=>{
// 處理操作路由的操作
res.writeHead(200, {
"Content-Type": "text/html;charset=UTF-8"
});
res.end('訪問操作頁面');
},
doLogin: (req,res)=>{
// 處理返回的post請(qǐng)求路由
let postStr = ''
req.on('data',(chunk)=>{
postStr += chunk;
});
req.on('end', ()=>{
console.log(postStr);
res.end(postStr)
})
},
error: (req,res)=>{
// 處理不存在的路由
res.writeHead(404, {
"Content-Type": "text/html;charset=UTF-8"
});
res.end('訪問頁面不存在');
},
// ----------->
}
module.exports = app;
此時(shí)的app.js修改為如下內(nèi)容
const http = require('http');
const url = require('url');
let routers = require('./modules/routers.js');
http.createServer((req, res) => {
routers.static(req, res, 'static');
// 獲取路由名稱
let pathName = url.parse(req.url).pathname.replace('/','');
try {
routers[pathName](req,res);
} catch (error) {
routers['error'](req,res);
}
}).listen(3000);
console.log("Server runing at http://127.0.0.1:3000");