前言
之前一直寫前端,瞭解過後端但是沒有具體實現過介面。最近在學node,所以用express搭建了一個簡易的後臺,實現了登入註冊等功能,寫完這個Demo之後自己對後端的理解加深了一個層次,也瞭解了之前前後端沒有分離的MVC模式的模板渲染具體細節。
這個demo是一個很簡單的評論系統,使用者註冊登入之後釋出評論,頁面展示評論。其實可擴充套件性還是很高的,目前儲存資料用的檔案之後可以改為MongoDB或者Mysql,還可以新增刪除、查詢功能,這可以做一個論壇或者商城的評論元件。
本篇文章講一下實現思路以及過程中遇到的問題,一起學習吧。(原始碼見文章末尾)
效果圖
因為是重點是在後臺介面,所以前端樣式很簡單
專案目錄
我用的express快速搭建生成的,生成好了之後自動在app.js檔案中匯入依賴項
# 安裝express-generator
$ npm install express-generator -g
# 快速搭建專案骨架
$ express -e proName
複製程式碼
目錄細節
- public ---靜態資源
- data.json -----評論資料以及使用者資料
- img、js、css
- routes -----路由
- index.js ----- 頁面路由
- data.js ----- 資料介面路由
- views ----- 頁面模板
- app.js ------ 專案入口
思路
我們將頁面部署在localhost:3000埠,瀏覽器根據index.js裡的頁面路由請求相應頁面。頁面所有和資料有關的操作介面,比如使用者註冊、釋出評論等放在data.js中,將路由分為頁面路由和資料路由,這樣結構更清晰一些。
view用的ejs,渲染方式為下面的第二種,這和我們平時的html不太一樣,ejs是js的模板庫,就好像Java的jsp一樣。
渲染資料有兩種方式:
- 就像上一篇文字聊天室那樣直接將html傳送給客戶端,然後通過ajax獲取資料讓js來渲染
- 將資料匯入模板在後端渲染好了將渲染好的html傳送給客戶端,這種方式是以前所謂的前後端不分離。
程式碼講解
評論系統的邏輯是:使用者註冊登入之後釋出評論,評論展示在皮膚上。
// 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模板。
// 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標籤進行跳轉的,比如
<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
複製程式碼
這裡可能有一個疑問:
- /data/write介面只是將傳來的資料儲存到了檔案,data.json的資料更新之後新資料怎麼渲染上home.ejs的?
先理一下index.js,當路由為'/'時我們將從data.json中讀取的資料渲染到home.ejs模板,當我們釋出評論之後,通過/data/write介面將新評論寫入data.json,寫入成功後返回data,data.status=1。在send.js的ajax的success中,當data.status=1時我們就重新整理頁面。home.ejs自然就會重新渲染了。 - 關於模板渲染不得不說的:
瀏覽器每向伺服器請求一次,通俗的說也就是頁面每重新整理一次,模板就會重新渲染一次。
結語
- 這個專案採用的MVC,M是資料(data.json和user.json),V(view)是ejs模板,C(路由)負責渲染模板與資料。
- 原始碼地址:windlany/express-comment,可以fork下來根據自己的需求改改,覺得不錯請給我一個star。