目录结构如下
app.js
// 一.引入模块
var http = require('http');// 用于创建 HTTP 服务器和处理 HTTP 请求
var fs = require('fs');// 用于读取和写入文件
var url = require('url');// 用于解析URL// 创建留言数据对象
var msgs = [{ name: '牛二', content: "我是妞儿", create_at: '2024-1-04 06:12' },{ name: '张三', content: "我是张三", create_at: '2024-1-22 09:32' },{ name: '里斯', content: "我是里斯", create_at: '2024-2-23 12:28' },{ name: '王五', content: "我是王五", create_at: '2024-4-14 17:11' }
];// 二.创建 HTTP 服务器实例
var server = http.createServer();// 三.监听用户请求
server.on('request', function (req, res) {// 获取当前请求地址var currentUrl = req.url;//判断页面if (currentUrl == '/') {// 首页(fs模块)fs.readFile('./views/index.html', 'utf8', function (err, data) {if (err) {console.log(err);return;}// res.end(data);// data 是首页所有的 html 代码// 1.将上面的变量数据组装到htmlvar html = '';msgs.forEach(function (item, index) {html += `<li class="list-group-item" style="display: flex; justify-content: space-between; align-items: center;">${item.name}: ${item.content}<span >${item.create_at}</span><button class="btn btn-danger btn-sm" onclick="deleteMessage(${index})">删除</button></li>`;});// console.log(html);// 2.重点!!替换 data 的占位符var htmlData = data.replace('^_^', html);// 3.响应替换后的数据res.end(htmlData);// 结束响应,并向客户端发送最终的响应内容})} else if (currentUrl == '/add') {// 添加页fs.readFile('./views/add.html', 'utf8', function (err, data) {if (err) {console.log(err);return;}res.end(data);})} else if (currentUrl.indexOf('/doadd') === 0) {// get 提交 /doadd?name=xxx&content=xxx req.url 请求路径需用url模块var parsedUrl = new URL(req.url, 'http://localhost:8080');// 创建新的 URL 对象,解析 req.url 来获取客户端请求的 URL,如 /add// 'ht...80' 是基础 URL,用于解析相对 URL,从而得到完整的 URL 地址var paramsObj = parsedUrl.searchParams;// 从解析后的 URL 对象中获取查询参数// 格式化日期时间var date = new Date();var hours = date.getHours();var minutes = date.getMinutes();var hoursStr = (hours < 10 ? '0' : '') + hours;var minutesStr = (minutes < 10 ? '0' : '') + minutes;var dateStr = date.getFullYear() + '-' + (date.getMonth() + 1) + '-' + date.getDate() + ' ' + hoursStr + ':' + minutesStr;var msg = {name: paramsObj.get('name'),content: paramsObj.get('content'),create_at: dateStr};// 理论上是给数据库添加一条数据,现在是向数组中压入一条数据msgs.push(msg); // 添加留言对象到留言数组中// 插入成功,重定向到首页res.statusCode = 302; // 声明重定向res.setHeader('location', '/'); //设置响应头,指定重定向到网站的根目录res.end() // 结束响应,并将其发送给客户端} else if (currentUrl.startsWith('/delete')) { // 当前请求的 URL 以 '/delete' 开头// 解析并删除对应索引var index = parseInt(currentUrl.split('/').pop());msgs.splice(index, 1);// 删除成功,重定向到首页res.statusCode = 302;res.setHeader('location', '/');res.end();}else {// 404fs.readFile('./views/404.html', 'utf8', function (err, data) {if (err) {console.log(err);return;}res.end(data);})}
})// 四.启动服务
server.listen(8080, function () {console.log('启动成功,访问:http://localhost:8080')
})// 注意
// 终端需要cd转到当前message目录下,再node app.js// currentUrl.indexOf('/doadd') === 0
// 通过 indexOf() 方法检查当前请求的 URL 是否以 /doadd 开头
// 如果返回 0,则表示当前 URL 的开头与 /doadd 完全匹配
// 如果匹配成功,条件语句将返回 true,否则返回 false
index.html
<!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>留言板</title><!-- 引入 Bootstrap 样式表 --><link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/3.4.1/css/bootstrap.min.css">
</head><body><!-- 头部容器 --><div class="header container"><!-- 页面标题栏 --><div class="page-header"><h1>留言板</h1><a class="btn btn-success" href="/add">发表留言</a><!-- 创建按钮链接到“/add”页,设置 Bootstrap 中的成功按钮 --></div></div><!-- 留言容器 --><div class="comments container"><ul class="list-group">^_^<!-- 占位符,表示在这里显示留言列表 --></ul></div><script>function deleteMessage(index) {if (confirm("确定要删除这条留言吗?")) {fetch(`/delete/${index}`, { method: 'DELETE' }).then(response => {if (response.ok) {window.location.reload(); // 删除成功后刷新页面} else {console.error('删除留言失败');}}).catch(error => {console.error('删除留言失败', error);});}}// 接受一个要删除的留言的索引参数 `index`// 函数首先弹出确认对话框,询问用户是否确定要删除该留言。// 如果确认,则通过 `fetch` 函数向服务器发送一个 DELETE 请求,// 该请求的路径包含了要删除的留言的索引。// 删除成功(即响应状态码为 200 OK),则刷新页面,以展示更新后的留言列表;// 删除失败,在控制台输出错误信息。</script></body></html>
add.html
<!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>发表留言</title><!-- 将 Bootstrap 的 CSS 文件引入到 HTML 页面中 --><link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/3.4.1/css/bootstrap.min.css"></head><body><!-- 头部容器 --><div class="header container"><!-- 页面标题栏 --><div class="page-header"><h1><a href="/">首页</a> <small>发表留言</small></h1></div></div><!-- 评论容器 --><div class="comments container"><!-- 创建表单,GET 提交到“/doadd”页 --><form action="/doadd" method="get"><div class="form-group"><label for="input_name">昵称</label><!-- 昵称输入框,设置类型为“name”,输入内容的最小和最大长度 --><input type="name" class="form-control" id="input_name" placeholder="请输入姓名" minlength="2" maxlength="10"name="name"></div><div class="form-group"><label for="input_message">留言内容</label><!-- 留言内容输入框,设置宽度30,高度10,必填,输入内容的最小和最大长度 --><textarea class="form-control" name="content" cols="30" rows="10" required minlength="5"maxlength="20"></textarea></div><!-- 提交按钮 --><button type="submit" class="btn btn-default">发表</button></form></div>
</body></html>
404.html
<!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>404</title>
</head><body><h1 style="text-align: center;">404!!!!</h1>
</body></html>
演示图片