Node.js實(shí)戰(zhàn)開發(fā):博客系統(tǒng)-創(chuàng)新互聯(lián)

一、需求分析
Node.js 實(shí)戰(zhàn)開發(fā):博客系統(tǒng)
Node.js 實(shí)戰(zhàn)開發(fā):博客系統(tǒng)
Node.js 實(shí)戰(zhàn)開發(fā):博客系統(tǒng)
Node.js 實(shí)戰(zhàn)開發(fā):博客系統(tǒng)
二、開發(fā)工具
1、NodeJs:基礎(chǔ)核心開發(fā)語言
2、express:一個簡潔而靈活的nodejs web應(yīng)用框架,提供一系列強(qiáng)大的特效幫助我們創(chuàng)建各種web應(yīng)用
從本質(zhì)上來說,一個 express 應(yīng)用就是在調(diào)用各種中間件。
3、mongodb:數(shù)據(jù)庫
4、第三方模塊/中間件
bodyParser:解析post請求數(shù)據(jù)
cookies:讀/寫cookie
swig:模板解析引擎
mongoose:操作mongodb數(shù)據(jù)
markdown:markdown語法解析生成模塊

成都創(chuàng)新互聯(lián)公司堅(jiān)持“要么做到,要么別承諾”的工作理念,服務(wù)領(lǐng)域包括:成都網(wǎng)站建設(shè)、成都網(wǎng)站設(shè)計、企業(yè)官網(wǎng)、英文網(wǎng)站、手機(jī)端網(wǎng)站、網(wǎng)站推廣等服務(wù),滿足客戶于互聯(lián)網(wǎng)時代的灌南網(wǎng)站設(shè)計、移動媒體設(shè)計的需求,幫助企業(yè)找到有效的互聯(lián)網(wǎng)解決方案。努力成為您成熟可靠的網(wǎng)絡(luò)建設(shè)合作伙伴!

require一個模塊,如果是通過npm安裝的或者是express內(nèi)置的模塊,直接require(‘模塊名’)
如果是自定義的模塊,必須加上相對路徑

三、開發(fā)實(shí)戰(zhàn)
1、構(gòu)建項(xiàng)目目錄結(jié)構(gòu)、安裝各種所需要的模塊框架等等
npm init
npm install --save XXX
2、目錄結(jié)構(gòu)
Node.js 實(shí)戰(zhàn)開發(fā):博客系統(tǒng)

3、創(chuàng)建應(yīng)用,監(jiān)聽端口

//app.js
var express = require("express");
var app = express();
var server = app.listen(8888, function(){
    console.log("Server is running on http://localhost:8888");
});

4、用戶訪問流程
用戶通過URL訪問web應(yīng)用,如:http://localhost:8888
web后端根據(jù)用戶訪問的URL處理不同的業(yè)務(wù)邏輯
5、路由綁定
通過app.get()或ap.post()等方法可以把一個url路徑和一個/N個函數(shù)進(jìn)行綁定

app.get( ‘/’,function(req,res,next){
    //req:request對象,保存客戶端發(fā)送請求的一些數(shù)據(jù)  === http.request
    //res:response對象,服務(wù)端輸出對象,提供了一些服務(wù)器端輸出的相關(guān)方法  === http.response
    res下面有write、end、statusCode、setHeader、writeHead等屬性和方法
    //next:方法,用于執(zhí)行下一個和路徑匹配的函數(shù)
} )

6.1、直接內(nèi)容輸出
通過res.send(string)發(fā)送內(nèi)容至客戶端
6.2、通過模板渲染內(nèi)容
res.render():將會根據(jù)views中的模板文件進(jìn)行渲染
如果不想使用views文件夾,想自己設(shè)置文件夾名字,那么app.set("views","aaaa");
注:如果想寫一個快速測試頁,當(dāng)然可以使用res.send(),send這個函數(shù)將根據(jù)內(nèi)容,自動幫我們設(shè)置了Content-Type頭部和200狀態(tài)碼。send()只能用一次,和end一樣。和end不一樣在哪里?能夠自動設(shè)置MIME類型。
7、模板的使用
后端邏輯和頁面表現(xiàn)分離-即前后端分離
8、模板的配置

var swig = require('swig');
app.engine('html',swig.renderFile);
//定義當(dāng)前應(yīng)用所使用的模板引擎,使用swig.renderFile方法解析為后綴為html的文件
app.set('views','./views');
//設(shè)置模板存放目錄
app.set('view engine','html');
//注冊模板引擎
swig.setDefault({cache:false});

9、設(shè)置靜態(tài)文件托管目錄
css、img、js等都通過下面的方法進(jìn)行托管
app.use('/public',express.static(dirname+'/public'));
在public目錄下劃分并且存放好相關(guān)的靜態(tài)資源文件
意思是:當(dāng)用戶訪問的url以/public開始,那么直接返回對應(yīng)
dirname+'/public'下的文件

10、前后端工作流程:
用戶發(fā)送http請求 -> 這個請求是一個url -> 后端解析url,提取信息 -> 找到匹配的規(guī)則 -> 滿足規(guī)則以后,執(zhí)行綁定函數(shù),返回對應(yīng)內(nèi)容給用戶

劃分:靜態(tài)文件、動態(tài)文件處理兩部分
靜態(tài)文件:
訪問/public下的文件 -> 靜態(tài)文件 -> 直接讀取指定目錄下的文件,直接渲染,返回給用戶
動態(tài)文件:
處理業(yè)務(wù)邏輯,加載模板,解析模板 -> 返回數(shù)據(jù)給用戶
通過路由匹配來獲取指定文件內(nèi)容

11、模塊劃分
根據(jù)功能進(jìn)行模塊劃分
前臺模塊 main.js
后臺管理模塊 admin.js
API模塊(頁面使用ajax請求的模塊)api.js
app.js:整個應(yīng)用的入口文件

//使用app.use()進(jìn)行模塊劃分
app.use('/admin',require('./router/admin'));  //請求admin.js,當(dāng)url匹配都/admin,就會請求./router/admin這個下面的admin.js文件,下面類似
app.use('/api',require('./router/api'));  //請求api.js
app.use('/',require('./router/main'));  //請求main.js

admin.js
let express = require('express');
let router = express.Router();
router.get('/',(req,res,next)=>{
    res.send('admin');
})
module.exports = router;

12、數(shù)據(jù)庫連接、表結(jié)構(gòu)Schema定義、Model創(chuàng)建
Node.js 實(shí)戰(zhàn)開發(fā):博客系統(tǒng)

進(jìn)入到mongoDB安裝目錄下的bin目錄,執(zhí)行命令:
mongod --dbpath=D:\妙味課堂文件夾\190122Nodejs開發(fā)博客系統(tǒng)\db --port=27017
定義數(shù)據(jù)庫存放位置和端口號
然后連接數(shù)據(jù)庫,這里通過可視化界面工具來連接數(shù)據(jù)庫:Robomongo軟件來連接

13、連接數(shù)據(jù)庫成功之后,在schemas文件夾下,新建用戶表結(jié)構(gòu),user.js,定義用戶的表
但是這里不是直接操作這個表結(jié)構(gòu)的,而是通過model模型類來對表進(jìn)行增刪改查,
model模型類:可以理解成對數(shù)據(jù)操作的封裝,Model中封裝對數(shù)據(jù)進(jìn)行處理的邏輯業(yè)務(wù)。

14、ajax發(fā)送請求的url地址:url : '/api/user/register',發(fā)送信息到后臺,后臺進(jìn)行接收前臺傳過來的數(shù)據(jù)

‘a(chǎn)pi/user/register’ 是解析router配置的第一級路徑'/api'的,然后在二級router下再匹配對應(yīng)的 ‘user/register’

對應(yīng)api.js文件下的 '/user/register' 路由
這里使用post請求,接收前端傳遞過來的數(shù)據(jù),使用body-parser中間件
使用:

//在入口文件app.js里面:
//加載body-parser,用來處理post提交過來的數(shù)據(jù)
var bodyParser = require('body-parser');
//bodyparser設(shè)置
app.use( bodyParser.urlencoded({extended: true}) );
這樣在模型類api.js里面,通過req.body就可以獲取到前端傳遞過來的值
router.post('/user/register',(req,res,next)=>{
    console.log(req.body);  //{ username: 'xiaoxiao', password: '11', repassword: '11' }
        res.json(responseData); //將responseData對象轉(zhuǎn)為json格式,返回給前端
})
就可以獲取到post提交過來的數(shù)據(jù),
反正前端通過post提交表單數(shù)據(jù),那么后端就可以通過req.body來獲取到該數(shù)據(jù)
數(shù)據(jù)的key值是input表單的name值,value值是用戶輸入的值

//查詢數(shù)據(jù)庫中相同用戶名和密碼的記錄是否存在,如果存在則登錄成功

15、獲取到了前臺傳遞過來的數(shù)據(jù)之后,后臺再進(jìn)入數(shù)據(jù)庫進(jìn)行操作,分2種情況:
注冊:此時,數(shù)據(jù)庫如果有該信用戶名,說明數(shù)據(jù)庫已經(jīng)存在,則返回信息給前端,提示用戶名已經(jīng)存在
數(shù)據(jù)庫如果沒有注冊信息,則需要把注冊信息存入數(shù)據(jù)庫,提示前臺注冊成功
這里面就涉及到了對數(shù)據(jù)的查找,可以使用find或者findOne進(jìn)行查找
沒有數(shù)據(jù)還要執(zhí)行存儲使用save進(jìn)行操作

16、
Request Headers:是瀏覽器向服務(wù)器發(fā)送請求的時候,傳遞給服務(wù)端的數(shù)據(jù)
Response Headers:是服務(wù)器發(fā)傳遞給客戶端的數(shù)據(jù)

17、渲染模板的同時帶入數(shù)據(jù)
res.render('admin/index',{
userCookie:req.userCookie //userCookie可以直接帶入到模板里面,使用{{}}就可以獲取到數(shù)據(jù)
})

18、模板的使用
在index頁面引入layout頁面:{% extends 'layout.html' %}
在index頁面重寫layout頁面內(nèi)容

layout頁面需要被重寫的內(nèi)容使用:{%block main%}{%endblock%}代替
index頁面,使用語法:
{% block main %}
//這里面是重寫的內(nèi)容
{% endblock %}
即把layout頁面需要被重寫的內(nèi)容剪切到index頁面,然后各自用語法代替,語法如上所示

19、各自路徑的設(shè)置
①、html頁面里的href路徑,需要寫全,即哪個路由下面的某某路徑,比如
<a href="/admin/user">用戶管理</a>
如果是三層,比如:<a href="/admin/category/add">添加分類</a>,那么對應(yīng)的請求接口為:
router.get('/category/add')
②、與此相對應(yīng)的,是router下面的路由文件,因?yàn)槁酚晌募?,比如本身已?jīng)命名為admin.js,那么下面請求的接口只需要寫router.get('/user')即可
③、res.render渲染的模板路徑,也要寫全,是哪個文件夾下的某某文件,比如:
res.render('admin/category_add'),后綴名可以不用寫
④<a href="/admin/category_add">添加分類</a>,跳轉(zhuǎn)到添加分類頁
這種寫法默認(rèn)是get請求,所以處理路由就得使用get進(jìn)行:router.get('/category_add')
如果要傳遞數(shù)據(jù)過去,在表單里面
<form action="/admin/category_add" method="POST" role="form"></form>
就使用router.post('/category_add')
地址都是/category_add,只不過一個是get請求,一個是post請求
⑥⑤

20、a鏈接點(diǎn)擊實(shí)現(xiàn)post方式提交,

<a href="/admin/category_edit?id={{item._id.toString()}}">修改</a>
//點(diǎn)擊頁面會跳轉(zhuǎn)到category_edit,匹配了get和post路由
router.get('/category_add')、router.post('/category_add')
//此時,form表單可以不需要寫action的url地址,因?yàn)檫€是在當(dāng)前頁,當(dāng)前頁的路由還是/category_add,還是會匹配到對應(yīng)的路由,執(zhí)行對應(yīng)的操作

對應(yīng)的form表單:

<form method="POST" role="form">
    <legend>修改分類</legend>

    <div class="form-group">
            <label for="">分類名稱</label>
            <input type="text" name="categoryName" value="{{categoryName}}" class="form-control" id="" placeholder="修改分類">
    </div>
    <button type="submit" class="btn btn-primary">提交</button>
</form>

post表單用于有前臺信息(一般是form表單)傳遞到后臺、其他情況可以使用get請求

錯誤集結(jié):
1、throw new TypeError('Router.use() requires a middleware function but got a ' + gettype(fn))
這種錯誤一般是模塊沒有導(dǎo)出,使用module.exports = 導(dǎo)出即可
2、Node.js 實(shí)戰(zhàn)開發(fā):博客系統(tǒng)
報錯:Cannot set headers after they are sent to the client
nodejs+express中出現(xiàn)這個錯誤都在路由里,大部分是程序運(yùn)行了res.xxx之后,后面還有和請求,響應(yīng)相關(guān)的操作造成的.
主要是程序運(yùn)行的先后順序沒理解透,也就是nodejs的一大特性 : 異步.初學(xué)者特別要注意.
-- 理解到了nodejs程序運(yùn)行的先后順序,這個問題就迎刃而解.
-- 還有就是res.xxx操作之后最好不要再有代碼,就算是打印輸出的代碼也寫在res.xxx之前,

-- 另外,nodejs程序就算res.xxx響應(yīng)以后,程序還會繼續(xù)執(zhí)行,return下更好.

3、Error: Failed to lookup view "index" in views directory "/views"
view模板文件目錄找不到
views錯誤與否取決你是怎么運(yùn)行app.js,我使用cmd到指定目錄下運(yùn)行app.js就不會出現(xiàn)這個問題,而使用webstorm直接運(yùn)行app.js就會出現(xiàn)這個問題。這個應(yīng)該是文件目錄的問題。想要在兩種方式下都可以找到views的方法是使用:

var path = require('path');
app.set('views', path.join(__dirname, 'views'));

4、報下面的錯誤
CastError: Cast to ObjectId failed for value "" at path "_id" for model "Category"
是因?yàn)椋簊ubmit提交還是在當(dāng)前頁面,路由不變,還是會走router.post('/category_edit'),而form表單加了action="/admin/category_edit",所以估計是重復(fù)報錯,刪掉form表單的action就行了;
以后注意:如果提交的頁面還是在當(dāng)前頁面,那么就不用加action了,當(dāng)前頁面不變,路由自然就會繼續(xù)執(zhí)行

另外有需要云服務(wù)器可以了解下創(chuàng)新互聯(lián)scvps.cn,海內(nèi)外云服務(wù)器15元起步,三天無理由+7*72小時售后在線,公司持有idc許可證,提供“云服務(wù)器、裸金屬服務(wù)器、高防服務(wù)器、香港服務(wù)器、美國服務(wù)器、虛擬主機(jī)、免備案服務(wù)器”等云主機(jī)租用服務(wù)以及企業(yè)上云的綜合解決方案,具有“安全穩(wěn)定、簡單易用、服務(wù)可用性高、性價比高”等特點(diǎn)與優(yōu)勢,專為企業(yè)上云打造定制,能夠滿足用戶豐富、多元化的應(yīng)用場景需求。

文章標(biāo)題:Node.js實(shí)戰(zhàn)開發(fā):博客系統(tǒng)-創(chuàng)新互聯(lián)
路徑分享:http://muchs.cn/article0/cspiio.html

成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供微信小程序、網(wǎng)站策劃、網(wǎng)站營銷自適應(yīng)網(wǎng)站、網(wǎng)站維護(hù)、虛擬主機(jī)

廣告

聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請盡快告知,我們將會在第一時間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場,如需處理請聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時需注明來源: 創(chuàng)新互聯(lián)

手機(jī)網(wǎng)站建設(shè)