1、先解决封装静态web 服务器
1)
- 先将 web-server文件夹 复制一份命名 web-server-fengzhuang 进行封装
- 将common.js 改成 routes.js 内容对应修改
const fs = require("fs");
const url = require("url");
const path = require("path");
// 私有方法
var getFileMine = function (extname) {
var data = fs.readFileSync("./data/test.json"); // 同步方法
var mimeObj = JSON.parse(data.toString());
return mimeObj[extname];
};
//导出部分命名为 static
exports.static = function (req, res, staticPath) {
// 1、读取地址
// var pathname = req.url;
var pathname = url.parse(req.url).pathname;
// console.log(url.parse(req.url));
// 需要加一点判断
pathname = pathname == "/" ? "/test.html" : pathname;
// 这个方法 可以获取后缀名 path.extname
var extname = path.extname(pathname);
// 2、通过fs 模块读取文件
if (pathname != "/favicon.ico") {
fs.readFile("./" + staticPath + pathname, (err, data) => {
if (err) {
res.writeHead(404, { "Content-Type": 'text/html;charset="utf-8"' });
res.end("404 这个界面不存在");
}
var mine = getFileMine(extname);
res.writeHead(200, { "Content-Type": "" + mine + ';charset="utf-8"' });
res.end(data);
});
}
};
2) app-1.js 也需要 修改一下
var http = require("http");
// 引入 routes.js
const routes = require("./module/routes");
http
.createServer(function (req, res) {
// 创建 静态web服务器
routes.static(req, res, "static");
})
.listen(3001);
3) node app-1.js 就可启动 服务 检查一下 对应 文件类型是正确的
2、路由
1)
- 比如页面 http://127.0.0.1:3001/login 表示登陆 /register表示注册 /admin表示后台管理
2)
routes.js 里先删除 404界面因为需要继续向下匹配路由 并加上这一句
if(!err){
var mine = getFileMine(extname);
res.writeHead(200, { "Content-Type": "" + mine + ';charset="utf-8"' });
res.end(data);
}
- app-1.js 里面开始 做判断和匹配操作
var http = require("http");
var url = require("url");
// 引入 routes.js
const routes = require("./module/routes");
http
.createServer(function (req, res) {
// 创建 静态web服务器
routes.static(req, res, "static");
// 路由
var 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 {
res.writeHead(404, { "Content-Type": ' text/html ;charset="utf-8"' });
res.end("页面不存在");
}
})
.listen(3001);
- routes.js 里面
// 2、通过fs 模块读取文件
if (pathname != "/favicon.ico") {
fs.readFile("./" + staticPath + pathname, (err, data) => {
// if (err) {
// res.writeHead(404, { "Content-Type": 'text/html;charset="utf-8"' });
// res.end("404 这个界面不存在");
// }
if (!err) {
var mine = getFileMine(extname);
res.writeHead(200, { "Content-Type": "" + mine + ';charset="utf-8"' });
res.end(data);
}
});
}
- 这时候 尝试 启动 node app-1.js 发现 可以 /login 不过 发生乱码
- 还有 一个问题 http://127.0.0.1:3001 展示 不出来了 排查一下 发现
fs.readFile()是异步方法 - 可以在这个地方改成
同步的fs.readFileSync() - 更改后是这样的
const fs = require("fs");
const url = require("url");
const path = require("path");
// 私有方法 不暴露出来 只在这个里面使用
var getFileMine = function (extname) {
var data = fs.readFileSync("./data/test.json"); // 同步方法
var mimeObj = JSON.parse(data.toString());
return mimeObj[extname];
};
//导出部分命名为 static
exports.static = function (req, res, staticPath) {
// 1、读取地址
// var pathname = req.url;
var pathname = url.parse(req.url).pathname;
// console.log(url.parse(req.url));
// 需要加一点判断
pathname = pathname == "/" ? "/test.html" : pathname;
// 这个方法 可以获取后缀名 path.extname
var extname = path.extname(pathname);
// 2、通过fs 模块读取文件
if (pathname != "/favicon.ico") {
try {
var data = fs.readFileSync("./" + staticPath + pathname);
if (data) {
var mine = getFileMine(extname);
res.writeHead(200, { "Content-Type": "" + mine + ';charset="utf-8"' });
res.end(data);
}
} catch (error) {}
}
};
- 重启 node app-1.js 发现 基本正常 不过
三个路由还是乱码状态 继续尝试解决 - 后面这种 东西 不要手动敲哈 偷偷把上面 也改了 应该没人知道
if (pathname == "/login") {
res.writeHead(200, { "Content-Type": ' text/html ;charset="utf-8"' });
res.end("执行登陆");
- 重启 后发现 问题 解决啦 nice
3、 EJS模版引擎
1) 将 web-server-fengzhaung 复制一份 然后 命名为 web-ejs
2) 在npmjs.com 搜索 ejs 然后 在 web-ejs 安装这个模块 npm install ejs
3)该文件夹下面 新建 views 写一个 文件 login.ejs 内容是 ejs 模版引擎
4) app-1.js 里面 增加一点内容
var ejs = require("ejs");
// if 判断里面 加上 这部分内容
if (pathname == "/login") {
var msg = "数据库里面获取的数据";
ejs.renderFile("./views/login.ejs", { msg: msg }, (err, data) => {
res.writeHead(200, { "Content-Type": ' text/html ;charset="utf-8"' });
res.end(data);
});
......
}
5) 执行 一下 node app-1.js 启动后
6) 可直接 将 数据库数据 展示 在页面上
- 这样做的好处是 数据库改变数据 网页随之刷新 就行
- 这个语法 有很多 可以直接 在ejs 上看
7) 接下来 我们再 模拟一个 在数据库拿到的数组 在页面渲染出来
- login.ejs 里面 这样写
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<h2>这是一个登陆页面</h2>
<h3><%=msg%></h3>
<ul>
<%for(var i=0;i < tlist.length; i ++){%>
<li><%=tlist[i].title%></li>
<%}%>
</ul>
</body>
</html>
- app-1.js 里面这样写
if (pathname == "/login") {
var msg = "数据库里面获取的数据";
var list = [
{ title: "test111" },
{ title: "test222" },
{ title: "test333" },
{ title: "test444" },
];
ejs.renderFile(
"./views/login.ejs",
{ msg: msg, tlist: list },
(err, data) => {
res.writeHead(200, { "Content-Type": ' text/html ;charset="utf-8"' });
res.end(data);
}
);
......
}
-
然后 node app-1.js 启动服务
-
后续 使用 需要继续 看 文档 先 学到这里
-
注意到一个规律 数据部分 写在
<%写在这个中间的位置%>
4、Get 请求
1)
2)回顾一下 我们 如何获取 地址后面的 get 传值呢 这部分 news?page=2&id=1 ?
比如现在有个网址是 http://127.0.0.1:3001/news?page=2&id=1
- nice 有了 这部分 基础 一切貌似 就简单了起来
- 我们 尝试继续完善一下 这部分功能
3)那么 我们在 app-1.js 稍微 改动一下
if (pathname == "/news") {
// 获取 get 传值
var query = url.parse(req.url).query;
console.log(query);
res.writeHead(200, { "Content-Type": ' text/html ;charset="utf-8"' });
res.end(query);
.........
}
-
重启 node app-1.js 然后写入 http://127.0.0.1:3001/news?page=2&id=1
-
就可看到数据
-
不过当前
打印出来的是 字符串 如何转化成对象呢 ? -
-
node app-1.js
-
控制台可以看到 结果
-
那么 我们 怎么看数据类型呢 ?
怎么确定是 get 请求呢 ?
5、 Post请求
1)我们 在 app-1.js 稍微 改动一部分 内容 看看post 的过程
2)在 views 文件夹 下面 新建 form.ejs 文件 里面写点内容
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<form action="/doRegister" method="post">
用户名:<input type="text" name="username">
<br>
<br>
密码: <input type="password" name="password">
<br>
<br>
<input type="submit" value="提交">
</form>
</body>
</html>
- app-1.js 里面 稍微改动一点
else if (pathname == "/register") {
//post 操作
ejs.renderFile("./views/form.ejs", {}, (err, data) => {
res.writeHead(200, { "Content-Type": ' text/html ;charset="utf-8"' });
res.end(data);
});
- node app-1.js
可看到
3) 下面一个 问题 post 值怎么传递呢 ?
- 需要 再做一个页面 获取 post传值
else if (pathname == "/doRegister") {
res.writeHead(200, { "Content-Type": ' text/html ;charset="utf-8"' });
res.end("post ok");
4)原生 node js 获取 post 的值
} else if (pathname == "/doRegister") {
// res.writeHead(200, { "Content-Type": ' text/html ;charset="utf-8"' });
// res.end("post ok");
// 获取 post 传值
var postData = "";
req.on("data", (chunk) => {
postData += chunk; // 通过对片段的拼接得到
});
req.on("end", () => {
console.log(postData);
res.end(postData); // 需要注意 这个地方是字符串形式可直接打印 对象形式不能直接打印出来
});
- node app-1.js