多应用+插件架构,代码干净,二开方便,首家独创一键云编译技术,文档视频完善,免费商用码云13.8K 广告
--- 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 )