---
title: node 入门之留言板
date: 2018-12-27 17:58:53
tags: nodejs
---
### node 入门 demo 一个前后端的 留言板
目前有三个版本
- 原生 node 无依赖版本
- 使用 express 的版本
- 使用 art-template模板引擎渲染的版本
### 需求分析:
- 首页 `展示留言列表`,`跳转至留言表单页面`
- 留言页 `用户输入表单,输入姓名,留言内容,`留言时间`, 提交返回列表页并更新渲染列表`
- 留言存储 `保存至 json 文件`,`用户留言后更新`
### 目录结构
![](https://ws4.sinaimg.cn/large/006tNbRwly1fylgknhn5lj307b07fmxb.jpg)
```
---public //存放静态资源
--css
--imgs
---views
--index.html //留言列表页
--posts.html //用户留言页面
---app.js //启动文件
---lists.json //留言存储文件
```
使用到的核心模块
`http`,`fs`,`url`
思路(以下为不使用任何第三方模块的方式):
- 根据 `request` 参数判断页面,使用 `fs`模块读取 html 页面返回。
- 每次请求列表页均从 json 文件 读取最新的数据 渲染
- 通过标识符替换 html 文本渲染列表
- 前端使用 form 表单提交留言数据,服务端存储并添加 时间字段
#### 服务端源码
```javascript
const http = require('http')
const fs = require('fs')
const url = require('url')
http
.createServer((req,res) => {
const date = new Date().toLocaleString('zh-CN') //请求时间
const parseObj = url.parse(req.url,true) //解析请求路径
const pathname= parseObj.pathname //路由名称
if(pathname === '/'){
fs.readFile('./views/index.html',(err,data)=>{
if(err){
return console.log('读取文件失败')
}
let tempStr = ''
fs.readFile('./lists.json', (error,lists)=>{
let cd = JSON.parse(lists)
cd.forEach(e => {
tempStr += `<li class="list-item">
<p class="list-name">${e.name}:</p>
<p class="list-content">${e.message}</p>
<p class="list-date">${e.date}</p>
</li>`
});
data = data.toString().replace('${{list}}',tempStr)
res.end(data)
})
})
}else if(pathname.includes('/public/')){ //public 目录静态资源
fs.readFile('.'+ pathname ,(err,data)=>{
if(err){
return console.log('读取文件失败')
}
res.end(data)
})
}else if(pathname === '/posts'){
fs.readFile('./views/posts.html',(err,data)=>{
if(err){
return console.log('读取文件失败')
}
res.end(data.toString())
})
}else if(pathname === '/shareMessage'){
fs.readFile('./lists.json', (err,data)=>{
if(err) return alert(err)
let cd = JSON.parse(data)
let message = parseObj.query
message.date = date
cd.unshift(message)
fs.writeFileSync('./lists.json',JSON.stringify(cd))
//跳转列表页面
res.statusCode = 302
res.setHeader('Location','/')
res.end()
})
}else{
fs.readFile('./views/404.html',(err,data)=>{
if(err){
return console.log('读取文件失败')
}
res.end(data.toString())
})
}
})
.listen(9999,()=>{
console.log('server running at http://localhost:9999');
})
```
#### index.html
```html
<div class="container">
<div class="header">
<h2>留言板 <span class="header-title">分享今日份喜悦</span></h2>
</div>
<div class="content">
<div class="content-header">
<button class="btn btn-primary" id="to-posts">去分享</button>
</div>
<ul class="lists">
<!-- 标识符 替换服务端模板 --!>
${{list}}
</ul>
</div>
</div>
```
#### posts.html
```html
<body background="/public/imgs/bea2.jpg">
<div class="container">
<div class="header">
<h2>留言板 <span class="header-title">分享今日份喜悦</span></h2>
</div>
<div class="content">
<form action="/shareMessage" tpye="GET">
<label for="name">
<span>留下大名</span>
<input type="text" name="name" required min-length="2" maxlength="15">
</label>
<label for="message">
<span>分享喜悦吧</span>
<textarea name="message" required min-length="5" maxlength="30" cols="30" rows="10" ></textarea>
</label>
<button type="submit" class="btn btn-default" id="post-message">发表喜悦</button>
</form>
</div>
</div>
</body>
```
#### 效果图
![](https://ws4.sinaimg.cn/large/006tNbRwly1fylhdugz90j31kt0u0kjr.jpg)
原生写起来路由部分太过繁琐, github 中 `version-1,version2`分支分别使用了 express 与 art-template 方式实现
[github 地址](https://github.com/Antelopeclouds/message-board )
- 01.let-const
- 02.对象数组解构&赋值
- 03.字符串扩展,数值扩展,数组扩展
- 04.数组扩展
- 05.对象扩展
- 06.06.Symbol原始数据类型
- 07.set数据结构
- 08.map数据结构
- 09.proxy与Reflect
- 10.类
- 11.Promise
- 12.Iterator(迭代器)
- 13.Generator(生成器)
- 14.module与模块化
- 15.es6学习总结
- 记录- Vue拖拽实例
- 记录-git使用天坑之分支切换
- node -- session & cookie & localStorge
- 18.12关于前端战略技术储备与问题反馈
- Vue组件通信方式总结以及遇到的问题
- 01.版本回溯以及文件修改
- 02.远端控制
- 03.分支管理
- node 入门 留言板
- nodejs模块与 commonjs 规范
- 19年技术发展规划
- JS错误处理 -> 提升程序健壮性
- Git 基本使用
- 18年年终总结