使用Nodejs搭建一个简易的留言簿(完结)

1、下载Node.js,并配置环境变量。

Node.js下载及热更新

2、创建app.js文件

app.js文件的主要功能是创建本地服务器,并通过路由来读取相对应的文件,渲染页面。

const http = require('http');
const fs = require('fs');
const url = require('url');

const server = http.createServer();

// 使用Promise异步获取数据
function getData(path) {
    try {
        return new Promise((resolve, reject) => {
            fs.readFile(path, (err, data) => {
                if (err) {
                    reject('文件读取失败,请稍后再试!');
                } else {
                    resolve(data);
                }
            })
        })
    } catch (error) {
		return error;
    }

}
server.on("request", async (req, res) => {
	// 跳过网站图标获取请求
    if (req.url === '/favicon.ico') return;

    let data = ''; // 用于存储返回数据
    let _url = url.parse(req.url, true);  // 解析url,参数二为true表示解析query参数
    // 路径没访问index.html则默认显示主页面
    if (['/', '/index.html'].includes(_url.pathname)) {
        data = await getData('./resource/index.html');
    } else {
        switch (_url.pathname) {
        	// 1、页面发出ajax请求获取database.txt中的数据
            case '/fetchData':
                data = await getData('./resource/dataBase.txt');
                break;
                
            // 2、表单请求存储数据
            case '/saveData':
                fs.appendFileSync('./resource/dataBase.txt', JSON.stringify(_url.query) + '\n');
                data = '<script>location.href="/index.html"</script>'; // 跳转到信息展示页面
                break;
                
            // 3、渲染表单填写页面
            case '/writeMsg.html':
                data = await getData('./resource/writeMsg.html');
                break
            default:
                break;
        }
    }

    res.setHeader('Content-Type', 'text/html;charset=utf-8'); // 设置响应头
    res.end(data) // 渲染页面

}).listen(8080);
// 监听的是8080端口,服务启动后可以通过http://localhost:8080来访问,或者http://主机ip:8080,
// 启动后可以在局域网中通过你的ip+端口号访问。

3、编写html页面

注意:两个html和一个txt,这三个文件都存放在resource文件夹中,而app.js是在项目文件夹下。
即:项目文件夹包括:resource文件夹 和 app.js文件
resource文件夹包括:index.htmlwriteMsg.htmldataBase.txt

3.1 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>
    <style>
        #box {
            width: 600px;
            margin: 50px auto;
        }

        table {
            border-collapse: collapse;
            border-width: 0.1px;
            text-align: center;
            vertical-align: auto;
        }
    </style>
</head>

<body>
    <div id="box">
        <h1>Example Page Header</h1>
        <!-- 点击发表留言跳转到writeMsg页面 -->
        <a href="/writeMsg.html"><button>发表留言</button></a>
        <hr>
        <table border="1" width="100%">
            <tbody>
                <tr>
                    <th>序号</th>
                    <th>留言者</th>
                    <th>留言内容</th>
                </tr>
            </tbody>
        </table>
    </div>
    <script>
        let result = '';  // 存储ajax响应体的变量
        const xhr = new XMLHttpRequest(); // 创建ajax实例
        // 1、设置发送路径以及发送方式,获取数据。/fetchData就是pathname,服务器通过路由返回响应。
        xhr.open('GET', '/fetchData'); 
        // 2、发出ajax请求
        xhr.send();
        // 3、ajax状态监听事件
        xhr.onreadystatechange = function () {
            /*
             * readystate是xhr对象中的属性,表示状态 0 1 2 3 4
             *  0:表示未初始化
             *  1:表示open方法调用完毕
             *  2:表示send方法调用完毕
             *  3:表示服务端返回了部分的结果
             *  4:表示服务端返回了全部的结果
             */
            if (xhr.readyState === 4) {
                // 4、判断状态码,一般来说200-299这个区间为正常返回。
                if (xhr.status >= 200 && xhr.status < 300) {
                    /**
                     * xhr.status   状态码
                     * xhr.statusText  状态字符串
                     * xhr.getAllResponseHeaders() 所有响应头
                     * xhr.response  响应体  
                     */
                    // 5、得到响应体。这里就成功获取到了数据
                    result = xhr.response
                    // 6、获取tbody节点
                    let tbody = document.querySelector('tbody'); 
                    // 7、切割信息,因为dataBase文件中的数据是一行一行存放的,所以通过换行符切割
                    let info = result.split('\n');
                    // 8、调用信息行函数,将返回的离线DOM添加到tbody中,大功告成。
                    infoRow(info, (tr) => {
                        tbody.appendChild(tr);
                    })
                } else {
                    result = xhr.status
                }
            }
        }

        // 传入的参数是数组对象,且里面是需要JSON.parse的对象。
        // 例如:['{\"userName\":\"测试3\",\"content\":\"123123\"}']
        function infoRow(info, callback) {
        	// 创建离线DOM,相当于用一个DOM盒子把你创建的真实DOM包裹起来,然后一并发出去。
            let offlineDOM = document.createDocumentFragment();
			// 遍历信息
            info.forEach((item, index, arr) => {
            	// 过滤掉为空的信息行
                if (item.trim() === '') return;
                // 创建tr,即:一行信息
                let tr = document.createElement('tr');
                // 解析JSON,让数据变为可用的对象
                item = JSON.parse(item);
                tr.innerHTML = `
                    <td>${index + 1}</td>
                    <td>${item.userName}</td>
                    <td>${item.content}</td>
                `;
                // 添加信息行
                offlineDOM.appendChild(tr);
            });
            // 通过回调返回DOM对象。
            callback(offlineDOM);
        }
    </script>
</body>
</html>

3.2 writeMsg.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>
    <style>
        #box{
            width: 600px;
            margin: 50px auto;
        }
        input,
        textarea {
            width: 100%;
            margin-top: 10px;
        }
    </style>
</head>

<body>
    <div id="box">
        <form action='/saveData' method="get">
            <input type="text" name="userName" placeholder="请输入姓名">
            <textarea rows="10" name="content" placeholder="留言内容"></textarea>
            <input id="submit" type="submit" value="提交" style="width: 50px;">
        </form>
    </div>
</body>
</html>

3.3 dataBase.txt

由于暂时没学MongoDB,所以就弄了个文本文件存储数据。

4、启动服务器

在项目文件夹中打开终端输入以下命令,如果安装了nodemon,则将node换成nodemon即可。

node app.js
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值