实验操作
新建一个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; // 获取到请求的url
pathName = url.parse(pathName).pathname; // 使用url内置模块获取路径名
pathName = pathName !== '/' ? pathName : '/index.html' // 获取到/就默认为/index.html
let extname = path.extname(pathName); // 使用内部模块path获取文件后缀名
if (pathName !== "/favicon.ico") {
fs.readFile(path.join(__dirname, '../static') + pathName, (err, data) => {
// 使用path根据当前路劲获得读取文件的相对路径
if (err) {
res.writeHead(404, {
"Content-Type": "text/html;charset=UTF-8"
});
res.end('404这个网页不存在');
}
let mime = common.getMime(extname); // 使用自定义模块根据后缀名获取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 函数所列举的类并不完整,引入完整的对应关系需要使用一个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中使用方式一,此时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; // 获取到请求的url
pathName = url.parse(pathName).pathname; // 使用url内置模块获取路径名
pathName = pathName !== '/' ? pathName : '/index.html' // 获取到/就默认为/index.html
let extname = path.extname(pathName); // 使用内容模块path获取文件后缀名
if (pathName !== "/favicon.ico") {
fs.readFile(path.join(__dirname, './static') + pathName, async (err, data) => {
// 使用path根据当前路劲获得读取文件的相对路径
if (err) {
res.writeHead(404, {
"Content-Type": "text/html;charset=UTF-8"
});
res.end('404这个网页不存在');
}
// let mime = common.getMime(extname); // 使用自定义模块根据后缀名获取Content-Type的值
let mime = await common.getFileMime(extname); // 使用自定义模块根据后缀名获取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
封装静态web服务
新建/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; // 获取到请求的url
pathName = url.parse(pathName).pathname; // 使用url内置模块获取路径名
pathName = pathName !== '/' ? pathName : '/index.html' // 获取到/就默认为/index.html
let extname = path.extname(pathName); // 使用内容模块path获取文件后缀名
if (pathName !== "/favicon.ico") {
try {
let data = fs.readFileSync('../' + staticPath + pathName); // 同步操作
if(data){
let mime = getFileMime(extname); // 使用自定义模块根据后缀名获取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 常用标签
<% %>流程控制标签
<%= %>输出标签(原文输出 HTML 标签)
<%- %>输出标签(HTML 会被浏览器解析)
<% for(var i = 0 ; i < news.length ; i++){ %> - <%= news[i] %>
<% } %>
先安装ejs: npm install ejs --save
新建views/login.ejs文件
Document
这是一个登录页面
<%=msg%>
<%for(let i=0; i < list.length; i++){ %>
-
<%=list[i].title%>
<%}%>
然后在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 = "这是数据库传回的数据";
let list = [
{ title: '标题1' },
{ title: '标题2' },
{ title: '标题3' },
{ title: '标题4' },
{ title: '标题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('正在操作注册页面')
} else if (pathName === '/admin') {
res.writeHead(200, {
"Content-Type": "text/html;charset=UTF-8"
});
res.end('处理之后的业务逻辑')
} 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");
获取请求方法名
req.method;
GET请求
获取 GET 传值:
var urlinfo=url.parse(req.url,true).query;
在app.js中添加/news的路由,并在浏览器的地址栏中输入http://localhost:3000/news?id=1&page=2
实现get请求,
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('这是一个登录页面')
} 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('处理之后的业务逻辑')
} else if (pathName === '/news') {
// 获取请求方法名
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请求成功')
}
}).listen(3000);
console.log("Server runing at http://127.0.0.1:3000");
POST请求
获取 POST 传值:
var postData = '';
// 数据块接收中
req.on('data', function (postDataChunk) {
postData += postDataChunk;
});
// 数据接收完毕,执行回调函数
req.on('end', function () {
try {
postData = JSON.parse(postData);
} catch (e) {}
req.query = postData;
console.log(querystring.parse(postData));
});
新建views/form.ejs
Document
在app.js中修改logoin路由中的内容并以及新增一个/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对象封装静态方法和路由访问
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; // 获取到请求的url
pathName = url.parse(pathName).pathname; // 使用url内置模块获取路径名
pathName = pathName !== '/' ? pathName : '/index.html' // 获取到/就默认为/index.html
let extname = path.extname(pathName); // 使用内容模块path获取文件后缀名
if (pathName !== "/favicon.ico") {
try {
let data = fs.readFileSync('./' + staticPath + pathName);
if(data){
let mime = getFileMime(extname); // 使用自定义模块根据后缀名获取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)=>{
// 处理注册路由的操作
res.writeHead(200, {
"Content-Type": "text/html;charset=UTF-8"
});
res.end('访问注册页面');
},
admin: (req,res)=>{
// 处理操作路由的操作
res.writeHead(200, {
"Content-Type": "text/html;charset=UTF-8"
});
res.end('访问操作页面');
},
doLogin: (req,res)=>{
// 处理返回的post请求路由
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;
此时的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.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");