1、搭建網站服務器:實現客戶端與服務端的通信
新建 user 文件夾,新建 app.js 文件:
// 用於創建網站服務器的模塊 const http = require('http'); // 創建服務器 const app = http.createServer(); // 為服務器端對象添加請求事件 app.on('request', (req, res) => { // 響應 res.end('ok'); }); // 監聽端口 app.listen(3000); console.log('服務器已啟動')
在命令行工具中,切換到 user 目錄下,開啟服務:
nodemon app.js
表示服務器啟動成功了
2、連接數據庫,創建用戶集合,向集合中插入文檔
引入mongoose第三方模塊 用來操作數據庫
// 引入mongoose第三方模塊 用來操作數據庫 const mongoose = require('mongoose'); // 數據庫連接 27012 是 MongoDB 的默認端口 mongoose.connect('mongodb://localhost/playground', { useNewUrlParser: true, useUnifiedTopology: true}) .then(() => console.log('數據庫連接成功')) .catch(err => console.log(err, '數據庫連接失敗'));
27017 是 MongoDB 的默認端口,可以不寫
保存后可以看到:
2.2、創建用戶集合
創建用戶集合規則:
// 創建用戶集合規則 const userSchema = new mongoose.Schema({ name: { type: String, required: true, minlength: 2, maxlength: 20 }, age: { type: Number, min: 18, max: 80 }, password: String, email: String, hobbies: [String] }); // 創建用戶集合 const User = mongoose.model('User', userSchema);
2.3、向集合中插入文檔
mongoimport -d playground -c users --file ./user.json
結果: imported successfully. 6 document(s) failed to import.
說明成功導入6條數據。
3、當用戶訪問 /list 時,將所有用戶信息查詢出來
3.1、實現路由功能
引入系統模塊 url ,用於處理 url 地址
// 引入系統模塊url 用於處理 url 地址 const url = require('url'); // 為服務器端對象添加請求事件 app.on('request', (req, res) => { // 請求方式 const method = req.method; // 請求地址 const { pathname } = url.parse(req.url); // 判斷請求方式 if (method == 'GET') { // 呈現用戶列表頁面 if (pathname == '/list') { } } else if (method == 'POST') { } // 響應 res.end('ok'); });
3.2、呈現列表頁面
// 呈現用戶列表頁面 if (pathname == '/list') { let list = `<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>用戶列表</title> <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap@3.3.7/dist/css/bootstrap.min.css"> </head> <body> <div class="container"> <h6> <a href="add.html" class="btn btn-primary">添加用戶</a> </h6> <table class="table table-striped table-bordered"> <tr> <td>用戶名</td> <td>年齡</td> <td>愛好</td> <td>郵箱</td> <td>操作</td> </tr> <tr> <td>張三</td> <td>20</td> <td> <span>抽煙</span> <span>喝酒</span> <span>燙頭</span> </td> <td>zhangsan@itcast.cn</td> <td> <a href="" class="btn btn-danger btn-xs">刪除</a> <a href="" class="btn btn-success btn-xs">修改</a> </td> </tr> </table> </div> </body> </html> `; res.end(list); }
在命令行工具中切換到 user 目錄下,輸入:
nodemon app.js
然后打開瀏覽器,輸入:http://localhost:3000/list
可以看到頁面:
3.3、從數據庫中查詢用戶信息,將用戶信息展示在列表中
通過 User.find() 查詢用戶信息
要用異步函數的方式:
// 為服務器端對象添加請求事件 app.on('request', async (req, res) => { // 請求方式 const method = req.method; // 請求地址 const { pathname } = url.parse(req.url); // 判斷請求方式 if (method == 'GET') { // 呈現用戶列表頁面 if (pathname == '/list') { // 查詢用戶信息 let users = await User.find() console.log(users); 。。。。。。
然后回到瀏覽器刷新頁面,在打開命令行工具,就可以看到查詢的用戶信息
4、將用戶信息和表格 HTML 進行拼接,並將拼接結果響應回客戶端
下面就要將查詢出來的數據和 list 的 HTML 代碼進行拼接。
把 list 的字符串,拆分為幾個小字符串,然后進行拼接。
第一段字符串:
let list = `
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>用戶列表</title>
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap@3.3.7/dist/css/bootstrap.min.css">
</head>
<body>
<div class="container">
<h6>
<a href="add.html" class="btn btn-primary">添加用戶</a>
</h6>
<table class="table table-striped table-bordered">
<tr>
<td>用戶名</td>
<td>年齡</td>
<td>愛好</td>
<td>郵箱</td>
<td>操作</td>
</tr>
`;
第三段字符串:
list += `
</table>
</div>
</body>
</html>
`;
第二段字符串:
// 對數據進行循環操作
users.forEach(item => {
list += ` <tr> <td>${item.name}</td> <td>${item.age}}</td> <td> <span>抽煙</span> <span>喝酒</span> <span>燙頭</span> </td> <td>${item.email}/td> <td> <a href="" class="btn btn-danger btn-xs">刪除</a> <a href="" class="btn btn-success btn-xs">修改</a> </td> </tr> `; });
此時在瀏覽器刷新頁面,已經可以動態顯示用戶信息列表
下面就是“愛好”字段的拼接,再進行下拆分:
// 對數據進行循環操作
users.forEach(item => {
list += ` <tr> <td>${item.name}</td> <td>${item.age}</td> <td> `; item.hobbies.forEach(item => { list += `<span>${item}</span>`; }) list += `</td> <td>${item.email}</td> <td> <a href="" class="btn btn-danger btn-xs">刪除</a> <a href="" class="btn btn-success btn-xs">修改</a> </td> </tr>`; });
刷新頁面:
5、當用戶訪問 /add 時,呈現表單頁面,並實現添加用戶信息功能
5.1、當用戶訪問 /add 時,呈現表單頁面
添加表單頁面
if (pathname == '/list'){ 。。。。。。 } else if (pathname == '/add') { let add = ` <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>用戶列表</title> <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap@3.3.7/dist/css/bootstrap.min.css"> </head> <body> <div class="container"> <h3>添加用戶</h3> <form> <div class="form-group"> <label>用戶名</label> <input type="text" class="form-control" placeholder="請填寫用戶名"> </div> <div class="form-group"> <label>密碼</label> <input type="password" class="form-control" placeholder="請輸入密碼"> </div> <div class="form-group"> <label>年齡</label> <input type="text" class="form-control" placeholder="請填寫年齡"> </div> <div class="form-group"> <label>郵箱</label> <input type="email" class="form-control" placeholder="請填寫郵箱"> </div> <div class="form-group"> <label>請選擇愛好</label> <div> <label class="checkbox-inline"> <input type="checkbox" value="足球"> 足球 </label> <label class="checkbox-inline"> <input type="checkbox" value="籃球"> 籃球 </label> <label class="checkbox-inline"> <input type="checkbox" value="橄欖球"> 橄欖球 </label> <label class="checkbox-inline"> <input type="checkbox" value="敲代碼"> 敲代碼 </label> <label class="checkbox-inline"> <input type="checkbox" value="抽煙"> 抽煙 </label> <label class="checkbox-inline"> <input type="checkbox" value="喝酒"> 喝酒 </label> <label class="checkbox-inline"> <input type="checkbox" value="燙頭"> 燙頭 </label> </div> </div> <button type="submit" class="btn btn-primary">添加用戶</button> </form> </div> </body> </html> `; res.end(add); }
在瀏覽器輸入:http://localhost:3000/add
可以看到表單頁:
下面要實現點擊“添加按鈕”可以跳轉到表單頁面的路由:
<a href="/add" class="btn btn-primary">添加用戶</a>
回到瀏覽器,刷新頁面,點擊“添加按鈕”,就可以跳轉到表單頁面了。
5.2、實現添加用戶信息功能
添加用戶請求要使用 Post:
<form method="POST">
為每一個表單字段添加子屬性 name:
<input name="name" type="text" class="form-control" placeholder="請填寫用戶名"> <input name="password" type="password" class="form-control" placeholder="請輸入密碼"> <input name="age" type="text" class="form-control" placeholder="請填寫年齡"> <input name="email" type="email" class="form-control" placeholder="請填寫郵箱"> <label class="checkbox-inline"> <input type="checkbox" value="足球" name="hobbies"> 足球 </label> <label class="checkbox-inline"> <input type="checkbox" value="籃球" name="hobbies"> 籃球 </label> <label class="checkbox-inline"> <input type="checkbox" value="橄欖球" name="hobbies"> 橄欖球 </label> <label class="checkbox-inline"> <input type="checkbox" value="敲代碼" name="hobbies"> 敲代碼 </label> <label class="checkbox-inline"> <input type="checkbox" value="抽煙" name="hobbies"> 抽煙 </label> <label class="checkbox-inline"> <input type="checkbox" value="喝酒"> 喝酒 </label> <label class="checkbox-inline"> <input type="checkbox" value="燙頭"> 燙頭 </label>
在 POST 路由里,增加一個路由:
else if (method == 'POST') { // 用戶添加功能 if ([pathname == '/add']) { } }
再回到 html 代碼部分的,from 表單添加請求地址:
<h3>添加用戶</h3> <form method="POST" action="/modify">
也就是說當用戶點擊“添加按鈕”的時候走到新增加的這個 POST 的“/add”路由。
在 POST 中添加 /add路由,然后可以測試下代碼:
else if (method == 'POST') { // 用戶添加功能 if ([pathname == '/add']) { console.log(123) } }
回到瀏覽器,刷新 /add 頁面,點擊下面的“添加用戶”按鈕,在命令行工具中,可以打印出:123
5.2.1、接收用戶提交的信息
// 用戶添加功能 if ([pathname == '/add']) { // 接收用戶提交的信息 let fromData= ''; // 當有參數傳遞的時候會觸發 data 事件 req.on('data', param => { fromData += param; }); // 當參數接收完畢的時候會觸發 end 事件 req.on('end', () => { console.log(fromData); }); }
回到瀏覽器中,隨便在表單中輸入一些內容后點擊按鈕提交,然后打開命令行工具可以看到:
下面要吧字符串轉換為對象的格式。
node 提供的內置模塊 querystring。
在 post.js 中導入 querystring 模塊:
// 處理請求參數模塊 const querystring = require('querystring');
使用 parse() 方法對參數的格式進行轉換:
req.on('end', () => {
console.log(querystring.parse(fromData));
});
回到瀏覽器重新提交內容,然后在命令行工具中可以看到:
5.2.2、將用戶提交的信息添加到數據庫中
// 當參數接收完畢的時候會觸發 end 事件 req.on('end', async () => { let user = querystring.parse(fromData) // 將用戶提交的信息添加到數據庫中 await User.create(user); // 重定向 狀態碼是301 // Location 跳轉地址 res.writeHead(301, { Location: '/list' }); res.end(); });
重新回到瀏覽器去添加信息,然后點擊"添加用戶"提交,成功后會自動跳轉到列表頁,內容增加了一條:
6、當用戶訪問 /modify 時,呈現修改頁面,並實現修改用戶信息功能
6.1、增加頁面路由 呈現頁面
6.1.1、在點擊修改按鈕時,將用戶 id 傳遞到當前頁面
修改按鈕部分代碼:
<a href="/modify?id=${item._id}" class="btn btn-success btn-xs" >修改</a>
增加 /modify 路由:
if (pathname == '/list') { } else if (pathname == '/add') { } else if (pathname == '/modify') { // 呈現修改用戶表單頁面 let modify = ` <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>用戶列表</title> <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap@3.3.7/dist/css/bootstrap.min.css"> </head> <body> <div class="container"> <h3>修改用戶</h3> <form method="POST" action="/add"> <div class="form-group"> <label>用戶名</label> <input name="name" type="text" class="form-control" placeholder="請填寫用戶名"> </div> <div class="form-group"> <label>密碼</label> <input name="password" type="password" class="form-control" placeholder="請輸入密碼"> </div> <div class="form-group"> <label>年齡</label> <input name="age" type="text" class="form-control" placeholder="請填寫年齡"> </div> <div class="form-group"> <label>郵箱</label> <input name="email" type="email" class="form-control" placeholder="請填寫郵箱"> </div> <div class="form-group"> <label>請選擇愛好</label> <div> <label class="checkbox-inline"> <input type="checkbox" value="足球" name="hobbies"> 足球 </label> <label class="checkbox-inline"> <input type="checkbox" value="籃球" name="hobbies"> 籃球 </label> <label class="checkbox-inline"> <input type="checkbox" value="橄欖球" name="hobbies"> 橄欖球 </label> <label class="checkbox-inline"> <input type="checkbox" value="敲代碼" name="hobbies"> 敲代碼 </label> <label class="checkbox-inline"> <input type="checkbox" value="抽煙" name="hobbies"> 抽煙 </label> <label class="checkbox-inline"> <input type="checkbox" value="喝酒"> 喝酒 </label> <label class="checkbox-inline"> <input type="checkbox" value="燙頭"> 燙頭 </label> </div> </div> <button type="submit" class="btn btn-primary">修改用戶</button> </form> </div> </body> </html> `; res.end(modify); }
回到瀏覽器中,隨便點擊一個“修改”按鈕,可以看到地址跳轉到:modify?id=5c09f267aeb04b22f8460968
6.1.2、從數據庫中查詢當前用戶信息,將用戶信息展示到頁面中
修改請求地址部分代碼:
// 請求地址 const { pathname, query } = url.parse(req.url, true);
query:保存了 get 請求參數,默認為字符串類型
true:表示將查詢參數解析成對象的形式
然后根據 id 查詢當前用戶信息
else if (pathname == '/modify') { let user = await User.find({'_id': query.id}) console.log(user) }
回到瀏覽器中刷新頁面,在命令行工具中可以看到當前用戶的信息:
我們可以看到返回的是數組形式,不是我們要的對象形式,所以要把 find 改為 findOne:
else if (pathname == '/modify') { let user = await User.findOne({'_id': query.id}) console.log(user) }
再刷新頁面。回到命令行工具可以看到:已經為對象了
將查詢出來的對象拼接到頁面中:
<input value="${user.name}" name="name" type="text" class="form-control" placeholder="請填寫用戶名"> <input value="${user.password}" name="password" type="password" class="form-control" placeholder="請輸入密碼"> <input value="${user.age}" name="age" type="text" class="form-control" placeholder="請填寫年齡"> <input value="${user.email}" name="email" type="email" class="form-control" placeholder="請填寫郵箱">
愛好等下再說,先到瀏覽器刷新頁面看下:已經把用戶信息展示出來了
愛好是在 hobbies 數組中的,我們需要在頁面中表現為選中的狀態,思路是:
先准備一個數組,把所有的愛好都存在這個數組里,然后循環這個數組。在循環的過程中,當前項的愛好是否為用戶的愛好,如果是的話,就給這個標簽增加選中狀態 checked;如果當前循環項不是用戶的愛好,我們就不增加選中標簽。
定義愛好數組:
let hobbies = ['足球', '籃球', '橄欖球', '敲代碼', '抽煙', '喝酒', '燙頭', '吃飯', '睡覺', '打豆豆'];
拆分 modify 字符串:
let hobbies = ['足球', '籃球', '橄欖球', '敲代碼', '抽煙', '喝酒', '燙頭', '吃飯', '睡覺', '打豆豆']; // 呈現修改用戶表單頁面 let modify = ` 、、、、、、 `; hobbies.forEach(item => { // 判斷當前循環項是否在用戶的愛好數組中,includes 當前參數是否在數組中 if (user.hobbies.includes(item)) { modify += `<label class="checkbox-inline"> <input type="checkbox" value="${item}" name="hobbies" checked> ${item} </label> ` } else { modify += `<label class="checkbox-inline"> <input type="checkbox" value="${item}" name="hobbies"> ${item} </label> ` } }) modify += `</div> </div> <button type="submit" class="btn btn-primary">修改用戶</button> </form> </div> </body> </html>`;
回到瀏覽器刷新頁面可以看到當前用戶的愛好是選中狀態了:
6.2、實現用戶修改功能
6.2..1、指定表單的提交地址以及請求方式 Post
回到 html 代碼部分的,from 表單的請求地址改為'/modify':
<h3>修改用戶</h3> <form method="POST" action="/modify">
也就是說當用戶點擊“修改按鈕”的時候走到新增加的這個 POST 的 “/modify” 路由。
在 POST 中添加 /modify 路由,然后可以測試下代碼:
else if (method == 'POST') { // 用戶添加功能 if ([pathname == '/add']) { 。。。。。。 } else if (pathname == '/modify') { console.log(789) } }
回到瀏覽器,刷新 /modify 頁面,點擊下面的“修改用戶”按鈕,在命令行工具中,可以打印出:789
6.2.2、在服務器端接收客戶端傳遞過來的修改信息,找到對應用戶,將用戶信息更改為最新的
然后把上面 /add 部分的代碼復制粘貼過來,再修改下:
else if (pathname == '/modify') { // 接收用戶提交的信息 let fromData= ''; // 當有參數傳遞的時候會觸發 data 事件 req.on('data', param => { fromData += param; }); // 當參數接收完畢的時候會觸發 end 事件 req.on('end', async () => { let user = querystring.parse(fromData) // 將用戶提交的信息更新到數據庫中 await User.updateOne({_id: query.id} ,user); // 重定向 狀態碼是301 // Location 跳轉地址 res.writeHead(301, { Location: '/list' }); res.end(); }); }
這里需要用到用戶 id,所以上面 from 表單的提交地址要把 id 帶上:
<h3>修改用戶</h3> <form method="POST" action="/modify?id=${user._id}">
然后回到瀏覽器刷新頁面,修改一些信息后,點擊“修改用戶”按鈕,可以看到結果:
7、當 用戶訪問 /delete 時,實現刪除用戶功能
7.1、給刪除按鈕添加鏈接,並攜帶 _id 參數:
<a href="/remove?id=${item._id}" class="btn btn-danger btn-xs">刪除</a>
7.2、在 GET 方式中創建 /remove 路由:
if (pathname == '/list') { 。。。。。。 } else if (pathname == '/add') { 。。。。。。 } else if (pathname == '/modify') { 。。。。。。 } else if (pathname == '/remove') { // 先通過 res.end 把參數 id 響應給客戶端 res.end(query.id); }
回到瀏覽器刷新頁面,點擊刪除按鈕,結果:跳轉到 /remove 路由並在頁面顯示 id
使用 findOneAndDelete 方法刪除用戶:
else if (pathname == '/remove') { // res.end(query.id); await User.findOneAndDelete({_id: query.id}); res.writeHead(301, { Location: '/list' }); res.end(); }
在瀏覽器中刷新頁面,點擊刪除按鈕:把 王五123 刪除掉了
現在整個項目的增刪改查功能都可以實現了,但是有兩個問題:
1、所有的代碼都寫在了一個頁面中,后期不好維護
2、頁面中有大量的字符串拼接,很容易出錯;而且后期 html 代碼有修改的話,會很困難
在 node.js 中采用模塊化管理,我們要根據代碼的功能,把代碼分離到不同的模塊中。比如說:數據庫連接以及用戶集合的創建,就要分離到不同的文件中。
解決問題1:
在 user 項目的根目錄下,創建 model 文件夾來放置一些和數據庫相關的文件。
在 model 文件夾下,新建 index.js 文件:
// 引入mongoose第三方模塊 用來操作數據庫 const mongoose = require('mongoose'); // 數據庫連接 27012 是 MongoDB 的默認端口 mongoose.connect('mongodb://localhost/playground', { useNewUrlParser: true, useUnifiedTopology: true}) .then(() => console.log('數據庫連接成功')) .catch(err => console.log(err, '數據庫連接失敗'));
在新建 user.js 文件:
// 引入mongoose第三方模塊 用來操作數據庫 const mongoose = require('mongoose'); // 創建用戶集合規則 const userSchema = new mongoose.Schema({ name: { type: String, required: true, minlength: 2, maxlength: 20 }, age: { type: Number, min: 18, max: 80 }, password: String, email: String, hobbies: [String] }); // 創建用戶集合 const User = mongoose.model('User', userSchema);
然后在 app.js 文件中,很多地方都用到了 User 這個集合構造函數,那么在 user.js 文件中,就應該把這個構造函數開放出去。
// 引入mongoose第三方模塊 用來操作數據庫 const mongoose = require('mongoose'); // 創建用戶集合規則 const userSchema = new mongoose.Schema({ name: { type: String, required: true, minlength: 2, maxlength: 20 }, age: { type: Number, min: 18, max: 80 }, password: String, email: String, hobbies: [String] }); // 創建用戶集合 const User = mongoose.model('User', userSchema); module.exports = User;
其他文件中引入 user.js 文件,就可以拿到 User 這個集合的構造函數了。
回到 app.js 文件中,引入 index.js 和 user.js :
require('./model/index');
const User = require('./model/user');
再打開瀏覽器中,刷新頁面,重新操作下各功能,發現沒有問題。
完整 app.js 代碼:
// 用於創建網站服務器的模塊 const http = require('http'); // // 引入mongoose第三方模塊 用來操作數據庫 // const mongoose = require('mongoose'); // 引入系統模塊url 用於處理 url 地址 const url = require('url'); // 處理請求參數模塊 const querystring = require('querystring'); require('./model/index'); const User = require('./model/user'); // // 數據庫連接 27012 是 MongoDB 的默認端口 // mongoose.connect('mongodb://localhost/playground', { useNewUrlParser: true, useUnifiedTopology: true}) // .then(() => console.log('數據庫連接成功')) // .catch(err => console.log(err, '數據庫連接失敗')); // // 創建用戶集合規則 // const userSchema = new mongoose.Schema({ // name: { // type: String, // required: true, // minlength: 2, // maxlength: 20 // }, // age: { // type: Number, // min: 18, // max: 80 // }, // password: String, // email: String, // hobbies: [String] // }); // // 創建用戶集合 // const User = mongoose.model('User', userSchema); // 創建服務器 const app = http.createServer(); // 為服務器端對象添加請求事件 app.on('request', async (req, res) => { // 請求方式 const method = req.method; // 請求地址 const { pathname, query } = url.parse(req.url, true); // 判斷請求方式 if (method == 'GET') { // 呈現用戶列表頁面 if (pathname == '/list') { // 查詢用戶信息 let users = await User.find() // console.log(users); // HTML字符串 let list = ` <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>用戶列表</title> <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap@3.3.7/dist/css/bootstrap.min.css"> </head> <body> <div class="container"> <h6> <a href="/add" class="btn btn-primary">添加用戶</a> </h6> <table class="table table-striped table-bordered"> <tr> <td>用戶名</td> <td>年齡</td> <td>愛好</td> <td>郵箱</td> <td>操作</td> </tr> `; // 對數據進行循環操作 users.forEach(item => { list += ` <tr> <td>${item.name}</td> <td>${item.age}</td> <td> `; item.hobbies.forEach(item => { list += `<span>${item}</span>`; }) list += `</td> <td>${item.email}</td> <td> <a href="/remove?id=${item._id}" class="btn btn-danger btn-xs">刪除</a> <a href="/modify?id=${item._id}" class="btn btn-success btn-xs" >修改</a> </td> </tr>`; }); list += ` </table> </div> </body> </html> `; res.end(list); } else if (pathname == '/add') { // 呈現添加用戶表單頁面 let add = ` <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>用戶列表</title> <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap@3.3.7/dist/css/bootstrap.min.css"> </head> <body> <div class="container"> <h3>添加用戶</h3> <form method="POST" action="/add"> <div class="form-group"> <label>用戶名</label> <input name="name" type="text" class="form-control" placeholder="請填寫用戶名"> </div> <div class="form-group"> <label>密碼</label> <input name="password" type="password" class="form-control" placeholder="請輸入密碼"> </div> <div class="form-group"> <label>年齡</label> <input name="age" type="text" class="form-control" placeholder="請填寫年齡"> </div> <div class="form-group"> <label>郵箱</label> <input name="email" type="email" class="form-control" placeholder="請填寫郵箱"> </div> <div class="form-group"> <label>請選擇愛好</label> <div> <label class="checkbox-inline"> <input type="checkbox" value="足球" name="hobbies"> 足球 </label> <label class="checkbox-inline"> <input type="checkbox" value="籃球" name="hobbies"> 籃球 </label> <label class="checkbox-inline"> <input type="checkbox" value="橄欖球" name="hobbies"> 橄欖球 </label> <label class="checkbox-inline"> <input type="checkbox" value="敲代碼" name="hobbies"> 敲代碼 </label> <label class="checkbox-inline"> <input type="checkbox" value="抽煙" name="hobbies"> 抽煙 </label> <label class="checkbox-inline"> <input type="checkbox" value="喝酒"> 喝酒 </label> <label class="checkbox-inline"> <input type="checkbox" value="燙頭"> 燙頭 </label> </div> </div> <button type="submit" class="btn btn-primary">添加用戶</button> </form> </div> </body> </html> `; res.end(add); } else if (pathname == '/modify') { let user = await User.findOne({'_id': query.id}); console.log(user) let hobbies = ['足球', '籃球', '橄欖球', '敲代碼', '抽煙', '喝酒', '燙頭', '吃飯', '睡覺', '打豆豆']; // 呈現修改用戶表單頁面 let modify = ` <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>用戶列表</title> <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap@3.3.7/dist/css/bootstrap.min.css"> </head> <body> <div class="container"> <h3>修改用戶</h3> <form method="POST" action="/modify?id=${user._id}"> <div class="form-group"> <label>用戶名</label> <input value="${user.name}" name="name" type="text" class="form-control" placeholder="請填寫用戶名"> </div> <div class="form-group"> <label>密碼</label> <input value="${user.password}" name="password" type="password" class="form-control" placeholder="請輸入密碼"> </div> <div class="form-group"> <label>年齡</label> <input value="${user.age}" name="age" type="text" class="form-control" placeholder="請填寫年齡"> </div> <div class="form-group"> <label>郵箱</label> <input value="${user.email}" name="email" type="email" class="form-control" placeholder="請填寫郵箱"> </div> <div class="form-group"> <label>請選擇愛好</label> <div> `; hobbies.forEach(item => { // 判斷當前循環項是否在用戶的愛好數組中,includes 當前參數是否在數組中 if (user.hobbies.includes(item)) { modify += `<label class="checkbox-inline"> <input type="checkbox" value="${item}" name="hobbies" checked> ${item} </label> ` } else { modify += `<label class="checkbox-inline"> <input type="checkbox" value="${item}" name="hobbies"> ${item} </label> ` } }) modify += `</div> </div> <button type="submit" class="btn btn-primary">修改用戶</button> </form> </div> </body> </html>`; res.end(modify); } else if (pathname == '/remove') { // res.end(query.id); await User.findOneAndDelete({_id: query.id}); res.writeHead(301, { Location: '/list' }); res.end(); } } else if (method == 'POST') { // 用戶添加功能 if (pathname == '/add') { // 接收用戶提交的信息 let fromData= ''; // 當有參數傳遞的時候會觸發 data 事件 req.on('data', param => { fromData += param; }); // 當參數接收完畢的時候會觸發 end 事件 req.on('end', async () => { let user = querystring.parse(fromData) // 將用戶提交的信息添加到數據庫中 await User.create(user); // 重定向 狀態碼是301 // Location 跳轉地址 res.writeHead(301, { Location: '/list' }); res.end(); }); } else if (pathname == '/modify') { // 接收用戶提交的信息 let fromData= ''; // 當有參數傳遞的時候會觸發 data 事件 req.on('data', param => { fromData += param; }); // 當參數接收完畢的時候會觸發 end 事件 req.on('end', async () => { let user = querystring.parse(fromData) // 將用戶提交的信息更新到數據庫中 await User.updateOne({_id: query.id} ,user); // 重定向 狀態碼是301 // Location 跳轉地址 res.writeHead(301, { Location: '/list' }); res.end(); }); } } // 響應 // res.end('ok'); }); // 監聽端口 app.listen(3000); console.log('服務器已啟動')
解決問題2:
通過模板引擎來解決,下面再繼續。