以前一直寫前端,瞭解事後端可是沒有具體實現過接口。最近在學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
複製代碼
這裏可能有一個疑問: