以前一直写前端,了解事后端可是没有具体实现过接口。最近在学node,因此用express搭建了一个简易的后台,实现了登陆注册等功能,写完这个Demo以后本身对后端的理解加深了一个层次,也了解了以前先后端没有分离的MVC模式的模板渲染具体细节。css
这个demo是一个很简单的评论系统,用户注册登陆以后发布评论,页面展现评论。其实可扩展性仍是很高的,目前存储数据用的文件以后能够改成MongoDB或者Mysql,还能够添加删除、查找功能,这能够作一个论坛或者商城的评论组件。html
本篇文章讲一下实现思路以及过程当中遇到的问题,一块儿学习吧。(源码见文章末尾)前端
由于是重点是在后台接口,因此前端样式很简单 node
我用的express快速搭建生成的,生成好了以后自动在app.js文件中导入依赖项mysql
# 安装express-generator
$ npm install express-generator -g
# 快速搭建项目骨架
$ express -e proName
复制代码
咱们将页面部署在localhost:3000端口,浏览器根据index.js里的页面路由请求相应页面。页面全部和数据有关的操做接口,好比用户注册、发布评论等放在data.js中,将路由分为页面路由和数据路由,这样结构更清晰一些。
view用的ejs,渲染方式为下面的第二种,这和咱们平时的html不太同样,ejs是js的模板库,就好像Java的jsp同样。
渲染数据有两种方式:git
评论系统的逻辑是:用户注册登陆以后发布评论,评论展现在面板上。github
// app.js
// some code
app.use('/', index); // 当请求为localhost:3000/时用index.js路由
app.use('/data', data); // 当请求为localhost:3000/data时用路由data.js
// some code
复制代码
根据该路由定向页面,res.render(page, data); -->用data数据渲染page模板。ajax
// index.js
var fs = require('fs'); // 导入会使用到的模块
var express = require('express');
var router = express.Router();
var path = './public/data/';
/* 当请求url为localhost:3000时渲染home.ejs返回给浏览器 */
router.get('/', function(req, res, next) {
fs.readFile(path+'data.json', (err, data) => { // 读取文件,并执行回调函数
if (err) {
return res.send({
status:0,
info: 'fail.....'
});
}
var obj = JSON.parse(data.toString()); // 返回数据
return res.render('home', { //不然,若是读取成功,渲染模板edit.jsp,返回数据obj
data: {
arr: obj,
name: req.cookies.username //登陆用户储存在cookie中
}
});
});
});
router.get('/login', function(req, res, next) {
res.cookie('username', '');
res.render('login', {});
});
router.get('/register', function(req, res, next) {
res.render('register', {});
});
router.get('/send', function(req, res, next) {
res.render('send', {
data: {
name: req.cookies.username
}
});
});
module.exports = router;
复制代码
在咱们的模板中咱们是用a标签进行跳转的,好比sql
<a href="/login">登陆</a> ---> 点击跳转到登陆界面
复制代码
以发布评论举例,当用户点击发布按钮时会发出一个ajax请求数据库
// send.js
$.ajax({
type: 'POST',
url: '/data/write',
dataType: 'json', // 预期服务器的返回类型
data: obj, // 将用户发送的评论做为数据传输出去
success: function(data) {
// some code
},
error: function() {
alert('发布评论失败,请重试!');
}
});
复制代码
相应的接收post请求的后台接口:
// data.js
//...some code
/* 发布评论 */
router.post('/write', function(req, res, next) {
if(!req.cookies.username) { // 若是用户未登陆
return res.send({
status: 2,
info: '请先登陆!'
});
}
var obj = {
username: req.cookies.username,
content: req.body.content
};
fs.readFile(path+'data.json', (err, data) => { // 读取文件,并执行回调函数
if (err) {
return res.send({
status:0,
info: '读取评论数据失败'
});
}
var arr = JSON.parse(data.toString()); // 获取文件数据
arr.splice(0, 0, obj); // 插入新评论数据
var newData = JSON.stringify(arr); // 转为json
// 将用户传来的评论加入数据库(data.json),由于我用的文件存储,后期能够改成MongoDB或mysql
fs.writeFile(path+'data.json', newData, function(err){
if(err){
return res.send({
status:0,
info: '添加评论数据失败'
});
}
return res.send({
status:1,
info: obj
});
});
});
});
// some code
复制代码
这里可能有一个疑问: