node.js 搭建blog
搭建開發環境并模擬交互數據
一、實驗說明
下述介紹為實驗樓默認環境,如果您使用的是定制環境,請修改成您自己的環境介紹。
三、功能模塊分析與設計
四、搭建開發環境
LouBlog 使用 nodeJS 搭建后臺,使用最受歡迎的 web 框架 Express 快速搭建。
有過 nodeJS 基礎的同學應該對此有一定的了解,簡單說一下,nodeJS 是基于 Chrome JavaScript 運行時建立的平臺,用于方便地搭建響應速度快、易于擴展的網絡應用。nodeJS 使用事件驅動,非阻塞 I/O 模型而得以輕量和高效。
再來介紹一下深受 nodeJS 開發者歡迎的 web 開發框架 Express 。Express 是一個基于 nodeJS 平臺的極簡、靈活的 web 應用開發框架,這好比如是 Flask 和 Python 的搭配一樣。Express 擁有豐富的 HTTP 快捷方法和任意排列組合的 Connect 中間件,方便快速、簡單地創建健壯、友好的 API
4.1 安裝node.js
1.安裝node.js參考菜鳥教程
http://www.runoob.com/nodejs/nodejs-install-setup.html
2.設置node.js環境變量,兩個
2.1
2.2 path添加node的安裝位置
4.2 使用Express生成項目框架
4.2.1 安裝 Express
在 Express v3.x 之前,還內置許多中間件,但在 v4.x 后,除了 static 都被分離為單獨的模塊,這也是許多初學者,面對的最大的問題,因為現在許多網上的文章還停留在 v3.x。
詳情可以訪問 Express中文網。
先通過 npm 全局安裝 Express:
sudo npm install -g express-generator
4.2.2 使用 Express
在安裝好 Express 開發框架及其命令行工具后,就可以快速生成我們需要的項目框架了。執行下面這條命令:
express -e LouBlog
成功后便會生成所需的框架。
文件結構如下
簡單了解一下 Express 都為我們準備好了什么:
LouBlog: 自然就是我們項目名,如果沒有此文件夾,在創建項目框架時加上名稱,就像剛剛執行完的那條命令,Express 就會自動幫我們創建此文件夾;若你在已是項目名的文件夾中生成框架,此項可省去。
public: 是我們項目的靜態資源,存放 imgs、js、css 等文件;
routes: 可以說是整個項目的控制部分,存放路由文件;
views: 存放項目的視圖文件;
bin: 存放可執行文件;
app.js: 項目的啟動文件;
package.json: 文件中有項目的基本信息,包括項目名、版本號、開放權限、啟動命令等;以及項目的模塊依賴信息,當運行 npm install 時, npm 就會此文件,并根據 dependencies 對象中的屬性安裝模塊。
簡單了解了 Express 為我們生成的框架,有沒有感受得到 Express 的強大呢,幫我做好了很多建站的基本工作,大大提高了效率。
注意:希望大家能多多學習生成的文件內容,尤其是 app.js 、routes/index.js 、bin/www 這幾個文件,
接下來我們做一點點修改,方便我們啟動項目服務,進入項目根目錄,并安裝項目的依賴模塊:
設置路由
修改 app.js 文件, 在文件最后的
module.exports = app; 之前添加一行代碼 app.listen(3000);
最后一部執行啟動命令:
node app.js
啟動項目,通過瀏覽器訪問 localhost:3000,即可看到結果
4.3 熟悉Express框架
4.3.1 工作原理
接下來學習 Express 框架中非常重要的路由控制。
routers/index.js 中有以下代碼:
代碼意思是當訪問主頁時,調用 ejs 模板(這里提到的 ejs 模板將會在下一節中詳細講解)來渲染 views/index.ejs 模板文件。 其中 get 指 http 的 get 請求方式,Express 封裝了許多 http 請求方式,我們主要使用 get() 和 post() 兩種;
?參數一:'/' 則代表了其路由規則,這里指向項目根目錄,同時路由規則還支持正則表達式,這給我們設計路由帶來很多的方便;
?參數二:為處理請求的回調函數,函數中又有兩個參數 req 和 res,代表請求信息和響應信息。
路徑請求及對應的獲取路徑有以下幾種形式:
?req.query: 處理get請求,獲取get請求參數。
?req.body: 處理post請求,獲取post請求體。
?req.params: 處理/:XXX形式的get或post請求,獲取請求參數
?req.param(): 處理get和post請求,但查找優先級由高到低為req.params -> req.body -> req.query。
res.render() 則將所有數據以 json 格式傳遞給模板引擎。
4.3.2 路由規則實踐
現在我們直接訪問 localhost:3000/login 會顯示:
這是因為我們還沒有建立 /login 這一路由規則
在 routers/index.js 文件中添加代碼
Ctrl + c 停止服務,node app.js 再次啟動服務,訪問 localhost:3000/login 后顯示:
出現這個錯誤是因為 view 中并沒用 login 對應的文件,添加 login.ejs 文件,文件中寫入 <%= title%>,直接刷新瀏覽器,這時便可以看到正確的顯示:
還記得之前簡單講解過 Express 生成的模板框架嗎,routes 中存放路由文件,views 中存放視圖文件,這就相當于 MVC 模式中的 C 和 V,而 index.ejs 文件中的 <%= title%> 是 ejs 模板引擎的語句,意思是將后臺傳遞來的 title 數據在頁面中顯示出來。
現在你應該大致了解了 Express 的路由工作原理,但在剛在的操作中,我們發現每次修改后臺代碼時,想要瀏覽修改結果,就需要先重啟服務。這無疑增加了開發的負擔。
使用 supervisor 模塊可以很好的解決這個問題,每當我們保存文件后,此模塊便會自動重啟服務,提高了開發效率。
首先要安裝此模塊:
配置啟動命令:
supervisor app.js之后,我們的項目啟動命名便從 node app.js 更改為
supervisor app.js這樣我們的開發環境已經初步配置完成,接下來我們根據 Express 的路由控制原則來設計我們的博客項目
五、搭建路由模塊
依據我們博客指定好的功能,我們初步設計以下幾個路由規則:
以上幾個路由規則分別對應“登錄”、“退出登錄”、“注冊”、“發表文章”、“查詢”、“編輯”、“刪除”功能。
再分別建立好對應的視圖文件:
“刪除”功能只是在請求完成后返回一個狀態信息,因此不必要創建視圖文件。
完成上面兩步,就需要在瀏覽器中依次測試剛剛設計好的路由規則是否有效果,有沒有報出錯誤,那這節實驗的任務就完成了。
六、前端模板引擎
6.1 什么是模板引擎
模板引擎是一個將頁面模板和數據數據結合起來生成 HTML 頁面的工具。通過模板引擎,我們可以在 HTML 文件中直接使用后臺傳遞過來的數據,而不必再使用通過解析 json 數據,在拼接成字符串的形式渲染數據,大大提高了開發效率。
6.2 什么是ejs
看過 Express API 的同學可能比較清楚,這里的 -e 正是指定 ejs 作為我們的模板引擎,而默認的模板引擎是 jade 。
那為何要選擇 ejs ,不選 jade?很大的一個原因是因為 ejs 的語法更符合前端開發者的習慣,項目的目的是為了能讓大家學會這一套開發流程,而不僅僅是一個模板引擎;反觀 jade ,很多初學者都很難馬上適應這中語法,更符合后臺開發者的習慣,特別是對縮進的嚴格要求,使得大家感覺與 Python 很像。
但這并不是說 jade 比 ejs 有多差,相反,有人做過測試,jade 的性能反而好過 ejs。這里只是為了大家快速上手開發,所以選擇了ejs。大家有時間也可以嘗試使用 jade 開發本課程,親身體驗一下二者的差別吧。
6.3 使用ejs
在 Express 自動生成項目框架時,有這么兩行代碼
這里設置了模板文件的存儲位置和使用的模板引擎。
在 routers/index.js 中通過 res.render() 渲染模板。它接收兩個參數,第一個是模板名稱,即 views 目錄下的模板文件名;第二個參數是傳遞給模板的數據對象。
舉個例子:當代碼為 res.render('index', {title: 'Express'}); 時,模板引擎會把 <%= title %> 替換為 Express ,然后把替換后的頁面展示給用戶。
相對于 jade 來說,ejs 非常簡單,只有三種標簽:
6.4 頁面布局
使用模板的一個原因,除了能方便處理數據,還有一點就是模板可以重用,我們可以將共用的部分分離為一個文件,并通過 include 引入。
6.4.1 分離共用模塊
ejs 模板引擎的 include 語法簡單粗暴,它不像許多模板能夠引入成對的標簽,而是硬生生將正常的 HTML 頁面截斷,直接將成對的標簽分在了不同的文件當中。
我們先來搭建一個首頁 index.ejs,課程最終完成的樣式如下:
希望大家能自由發揮你的創造力,建造有自己特色的樣式的博客,下面給出 index.ejs 的最簡代碼,通過不斷優化,來學習 ejs 模板及其他知識點。
<!DOCTYPE html><html><head><meta charset="UTF-8"><title><%= title %></title><link rel="stylesheet" href="/stylesheets/style.css"><body><nav><ul><li><a href="#">register</a></li><li><a href="#">login</a></li><li><a href="#">post</a></li><li><a href="#">logout</a></li></ul></nav><div id="container"><%= title %></div></body></html>從這個頁面的構造,以及我們之前的功能設計可以看出,
部分的導航條是共用部分,也就是在其頁面都有出現,這就可以用到 include 將其提取為一個文件。
使用 include 后的文件及內容:
views/header.ejs 文件:
views/footer.ejs 文件:
</div></body></html> 修改過后的 views/index.ejs 文件為: <%- include header %> <%= title %> <%- include footer %>以上便是 include 的簡單使用方法,ejs 模板引擎的基本功能也梳理完畢,在接下來的學習中,進一步體會 ejs 的魅力吧。
七、設計頁面
接下來,我們主要完成前端的展示部分,使用 bootstrap 前端框架快速搭建樣式優美的響應式頁面。
7.1 使用 bootstrap 前端框架
7.1.1 引入 bootstrap
注意:bootstrap 所有的 JavaScript 插件都依賴 jquery, 并且通過查看 bootstrap 的官方文檔就可以知道,bootstrap 所依賴的 jquery 版本最低為 v1.9.1,因此,還需要大家自己嘗試引入 jquery 文件。
再補充一下 bootstrap 的幾種安裝方式:
1.手動下載并導入項目:從官網下載所需的 bootstrap 開發包,選擇“用于生產環境的 bootstrap”,需要的文件為 fonts/*、js/bootstrap.min.js、css/bootstrap.min.css;
2.通過 npm 安裝:執行 npm install bootstrap --save。此時 bootstrap 就相當于一個模塊,通過 require('bootstrap') 導入后使用;
3.通過 bower 安裝:執行 bower install bootstrap。bower 是客戶端技術的軟件包管理器,方便管理客戶端依賴關系,在安裝 bootstrap 之前應該先執行 sudo npm install -g bower 全局安裝 bower;
4.使用CDN加速服務:bootstrap 中文網提供了免費的 CDN 加速服務,復制以下代碼,即可使用:
建議你使用 bower 安裝 bootstrap。
7.1.2 使用 bootstrap
在 viwes/header.ejs 中添加上面的代碼,并將
部分替換為 bootstrap 的導航條組件:
這段代碼中就是使用 bootstrap 的一個簡單例子,也只用到了導航條組件,除此之外,我們開發博客系統還可能用到表單樣式,柵格系統等,同學們可選擇合適的組件,當然也可以使用其他前端框架,比如 AmazeUI 等,開發自己的博客系統。
另外需要提出的一點是,在上面的導航條中,同時出現了“登錄”和“用戶信息”等邏輯上不該同時出現的按鈕。這就需要通過 session 機制來判斷用戶的登錄狀態,并返回應該顯示在頁面中的按鈕選項。這將在下一節,添加 mongoDB 后做詳細的講解。
7.2 自己搭建頁面樣式
這一步主要是使用 bootstrap 框架,搭建每一個功能模塊的頁面樣式,自己可以更具自己的喜好,自由發揮,在此列出每一個頁面必要的元素,以方便后期講解的統一。
views/login.ejs(登錄頁面):
構建一個 form 表單,需填寫的內容包括 “用戶名” 和 “密碼”。
views/register.ejs(注冊頁面):
一個 form 表單,需填寫的內容包括 “用戶名”、“密碼”、“確認密碼”和“郵箱”。
views/index.ejs(主頁):
主頁展示文章信息,有 “標題”、“作者”、“創建日期”、“標簽”和“文章內容”。
views/post.ejs(發表頁面):
form 表單,需要填寫的內容包括 “標題”,“標簽”和“文章內容”,至于 “作者”和“創建時間” 將通過其他方式記錄。
views/search.ejs(查詢結果頁面):
展示內容和主頁一致。
views/edit.ejs(編輯頁面):
form 表單,和發表頁面一致,需要自動填寫原有的數據,方便編輯。
7.3 模擬數據
接下來,我們通過修改 routes/index.js 向模板傳遞模擬數據,方便我們理解數據傳遞過程、編寫首頁樣式。
跳轉首頁的路由規則為:
上一節提到,res.render() 會將數據傳遞給模板,其中參數一便是對應的模板,這里便是 index.ejs,而數據便是{...} 這一對象。所以,我們編寫的模擬數據,就寫在這個對象里,以 json 格式為標準。
router.get('/', function(req, res, next) {res.render('index', {title: '主頁',arts: [{title: 'nodeJS入門',tags: 'nodeJS',author: '...',createTime: '',content: '...'},{title: 'nodeJS入門',tags: 'nodeJS',author: '...',createTime: '',content: '...'},{title: 'nodeJS入門',tags: 'nodeJS',author: '...',createTime: '',content: '...'}]}); });這里簡單添加了三條數據,模板 views/index.ejs 中添加:
<% arts.forEach(function(art) { %><%= art.title %><%= art.tags %><%= art.author %><%= art.createTime %> <%= art.content %> <% }) %>這樣,模板便成功的從后臺得到了數據,并展示到頁面中。頁面樣式很粗糙,這需要同學們自己完成。
八、本節總結
本節實驗簡單介紹了開發環境的搭建以及 Express 框架的使用,其中需要大家多花時間理解 Express 框架,從模板生成,到路由控制,希望大家能多看官網中的 API,熟悉 v3.x 和 v4.x 之間的區別,介紹了 ejs 模板的用法,熟悉 <% code %>、<%= code%>、<%- code%> 以及使用 <%- include views %> 進行模板重用是一重要知識點。
《mongoDB基礎教程》
使用 mongoDB 數據庫并整理功能模塊
一、實驗說明
下述介紹為實驗樓默認環境,如果您使用的是定制環境,請修改成您自己的環境介紹。
無需密碼自動登錄,系統用戶名shiyanlou
本實驗環境采用帶桌面的Ubuntu Linux環境,實驗中會用到桌面上的程序:
1.LX終端(LXTerminal): Linux命令行終端,打開后會進入Bash環境,可以使用Linux命令
2.Firefox:瀏覽器,可以用在需要前端界面的課程里,只需要打開環境里寫的HTML/JS頁面即可
3.GVim:非常好用的編輯器,最簡單的用法可以參考課程Vim編輯器
二、課程介紹
這一節,我們將學習在 Express 框架如何操作 mongoDB 中的數據,以及如何配合 session 完成一些基本的邏輯狀態判斷,完成本節,我們的 LouBlog 博客系統也將初具模型。
Mongodb安裝
https://www.mongodb.com/download-center#community
1.啟動數據庫
mongod.exe --dbpath c:\data\db
2.連接數據庫
mongod
3.查詢數據庫和使用數據庫和查找數據表
三、使用 mongoDB 數據庫
mongoDB 是一個基于分布式文件存儲的非關系型數據庫(NoSQL)的一種。它支持的數據結構非常松散,類似 json 的 bjson 格式。
mongoDB 沒有關系型數據庫中行和表的概念,但有類似文檔 (document)和集合(collection)的概念。文檔是 mongoDB 最基本的單位,集合是許多文檔的總和,一個數據庫可以有多個集合,一個集合可以有多個文檔。
因為實驗環境中默認安裝有 mongoDB 因此我們跳過安裝這一步,但先要通過以下指令開啟 mongoDB 服務;
開啟服務:
在根目錄下創建數據庫存儲目錄,并啟動服務:
sudo mkdir /data/db mongod最后輸入 mongo 即可訪問數據庫。
問題記錄:
運行mongodb出現計算機丟失api-ms-win-crt-runtime-|1-1-0.dll
解決:
http://blog.csdn.net/mblhq/article/details/53896920
3.1 連接 mongoDB
mongoDB 的服務啟動后,開始編寫程序建立連接,這里我們使用 mongoDB 的模型工具 -- mongoose,可以方便我們減化代碼,并且這還是為 nodeJS 設計的。
3.1.1 使用 mongoose 連接 mongoDB
運行以下命令安裝 mongoose 包:
接下需要修改 app.js,添加下面的代碼:
//先引入 mongoose 模塊 var mongoose = require('mongoose'); //連接數據庫 mongoose.connect('mongodb://localhost:27017/datas'); mongoose.connection.on('error', console.error.bind(console, '連接數據庫失敗'));刷新頁面時,若沒有報出 “連接數據庫失敗” 則成功連接數據庫。接下來,我們便要建立數據庫模型,向數據庫中存儲數據。
3.2 設置 schema
schema 是 mongoose 中的模型對象,就類似關系型數據庫中的表結構,為 key/value 的鍵值對形式。
我們的博客系統中主要存儲用戶和文章兩類數據,也就是需要建立兩個模型對象,暫且叫做 userSchema、articleSchema。
在根目錄下新建一個文件夾 models,再新建一個文件 model.js。
3.2.1 設置 userSchema
在 models/model.js 中引入 mongoose 模塊,并定義 schema 模型對象:
根據上一節實驗中,我們統一定義的用戶屬性有 “用戶名”、“密碼”和“郵箱”,可以確定模型中的屬性:username、password、email,此外考慮到以后操作數據的方便,在添加一個屬性createTime。
就可以創建具體的模型對象:
最后通過 mongoose 的 model() 方法,將 schema 發布為 model,model 具有抽象屬性和行為的數據庫操作對,這就使模型對象具有了數據庫的 CRUD 操作方法。
exports.User = mongoose.model('User', userSchema);
3.2.2 設置 articleSchema
同樣是在 models/model.js 下,我們創建文章模型對象 -- articleSchema:
注意:此處創建好的 model 對應數據庫中的集合,可以通過 show colections 查看數據庫中的所有集合。
創建好模型,就可以操作數據了。
3.3 操作數據
3.3.1 注冊用戶、發表文章
首先我們學習添加數據的操作 -- 注冊用戶和發表文章,在 routes/index.js 中,我們添加以下代碼:
這樣便實現了注冊功能,需要注意 req.body 處理 post 請求的參數,建立 User 模型對象實體操作數據庫,其實有 JavaScript 基礎的同學應該很熟悉這樣的寫法。
再來是文章發表功能,這時就要用到 articleSchema 模型對象:
有了用戶注冊的基礎,發表文章就簡單許多了,但現在還沒講到 session 的運用,author 元素的值可以暫時通過 post 表單獲得,稍后講到 session 時,我們再改為上面的寫法即可。
3.3.2 刪除文章
接下來是文章的刪除操作,依然是 routes/index.js,修改我們第一節實驗寫好的路由規則 /remove/:_id:
//mongoose 的 remove() 方法,通過傳遞檢索參數,直接刪除檢索結果
3.3.3 編輯文章
編輯文章,不僅需要獲取文章信息,初始化表單內容,同時還需要有和發表文章一樣的功能:
3.3.4 查詢文章
這里我們可以通過正則表達式,實現模糊查詢,因為 Express 路由規則支持正則匹配查詢。
完成以上四步,我們的博客系統就具有了基本的功能,但是還有幾個小問題:
?session 保存登錄狀態;
?控制訪問權限;
解決這兩個問題,就需要靠接下來我們將要學習的 session 。
四、創建 session
session 是一種持久網絡協議,在客戶端與服務器之間起到交換數據包的作用。用戶登錄后的基本信息都會保存其中,Express 也提供了會話中間件,同時我們還可以將會話信息存儲到數據庫中,便于維護。為此,我們需要引入兩個中間件 express-session 和 connect-mongo,安裝方式如下:
4.1 引入中間件,創建 session
接著我們要在 app.js 中添加以下代碼:
var session = require('express-session'); var MongoStore = require('connect-mongo')(session); //這里設置 session 參數,并確保以下代碼在 `app.use('/', routes)` 前引入 app.use(session({key: 'session',secret: 'keboard cat',cookie: {maxAge: 1000 * 60 * 60 * 24},//1daystore: new MongoStore({db: 'datas',mongooseConnection: mongoose.connection}),resave: false,saveUninitialized: true }));完成對 app.js 的以上修改之后,我們便能通過 req.session 獲取當前用戶的會話對象,獲取用戶的相關信息。
4.2 使用 session
舉兩個例子:
之前提到過的發表文章,其中的 author 屬性需要通過獲取 session 中保存的用戶信息,此處我們就可以修改發表文章的方法以實現我們的需求:
session 另一個很大的作用就是判斷用戶登錄狀態并控制頁面的元素顯示:
我們就修改上一節給出的導航條代碼,修改如下:
除了以上兩個例子,還有許多用到 session 的地方,大家在學習過程中可以自己好好感悟。
五、擴展功能
5.1 添加 flash 信息提示
上一節我們完成了博客系統的基本功能,但是有心的同學會發現,示例代碼里很多的 console.log() 信息提示,這是打印一些返回信息以幫助我們調試代碼,但不知有多少同學這樣思考過 -- 每次刷新調試,都要看服務程序的信息提示好不方便,要是刷新就能在頁面顯示這些提示可好,此外,用戶登錄,發表文章,成功還好,要是哪出錯了卻沒有任何提示多不方便。
恭喜你已經能夠主動思考、學習,接著往下你應該就會自己查詢解決辦法了吧。
只要走到這一步,相信大家就知道 flash 模塊能很好地幫助我們實現這一功能:
flash 存儲于 session 中,但與之前我們存入的用戶登錄信息不同,flash 信息將會在下一次刷新后被清楚。
首先還是安裝模塊,并引入:
這樣,我們便成功引入了 flash 模塊,接下來就可以將所有的 console.log() 使用 req.flash('type', content) 替換,其中參數一是一個字符串,代表了信息的類型,我們常用的就是 'success' 和 'error' 兩種,參數二就是信息的具體內容。
這只是將信息保存到了 session 中,想要在頁面中展示,我們就必須要從 session 中獲取并傳遞給 ejs 模板,方法如下:
模板獲得信息后就可以通過簡單的判斷語句展示這一內容:
<%if(success){ %><%=success %><% } %><%if(error){ %><%=error %><% } %>// error 同上,樣式可以通過 bootstrap 調整。問題:這樣許多頁面都需要信息提示,我們應該在何處做以上調整?
這就是我們添加 flash 信息提示的大致過程。
5.2 添加分頁功能
分頁功能是很常見的一個功能,當展示的信息條目很多時能分批次顯示,減小了瀏覽器壓力,避免渲染速度過慢。
要實現分頁的功能,主要需要考慮這幾個元素:“當前頁碼”,“每頁展示個數”,“條目總數”;此外分頁主要有兩種展示形式:“只有上/下一頁”,“展示多個頁碼”。我們就嘗試實現簡單的 “只有上/下一頁”。
修改 views/index.ejs:
將所有數據傳遞給模板后,剩余的事就簡單了許多。其中的 skip() 和 limit() 是實現分頁的關鍵部分,也有很多人說當數據量少的時候,skip() 的效率還可以,但當數據量很大的時候,效率就會很差。大家有興趣可以查閱資料,嘗試發現效率更高的方法。
Js使用express render的數據
六、本節總結
本節添加了mongoDB,并使用 mongoose 連接了數據庫,創建 session 判斷用戶狀態,完成了一些功能的擴展,使我們的 LouBlog 博客系統更充實。
再總結一下整個系列的實驗,提出了許多課程的知識點,示例代碼只是展示了核心部分,希望大家能嘗試在這種點到即止的方式中去查找解決辦法。
參考文檔:
作者:玄月府的小妖在debug
鏈接:https://www.jianshu.com/p/c890b7d56383
來源:簡書
簡書著作權歸作者所有,任何形式的轉載都請聯系作者獲得授權并注明出處。
總結
以上是生活随笔為你收集整理的node.js 搭建blog的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 不错的前端模板网站
- 下一篇: 2016 版 Laravel 系列入门教