---
title: node 入門之留言板
date: 2018-12-27 17:58:53
tags: nodejs
---
### node 入門 demo 一個前后端的 留言板
目前有三個版本
- 原生 node 無依賴版本
- 使用 express 的版本
- 使用 art-template模板引擎渲染的版本
### 需求分析:
- 首頁 `展示留言列表`,`跳轉至留言表單頁面`
- 留言頁 `用戶輸入表單,輸入姓名,留言內容,`留言時間`, 提交返回列表頁并更新渲染列表`
- 留言存儲 `保存至 json 文件`,`用戶留言后更新`
### 目錄結構

```
---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>
```
#### 效果圖

原生寫起來路由部分太過繁瑣, 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年年終總結