分析論壇項目
- 數(shù)據庫:總共兩個
- users:用戶數(shù)據究反,管理用戶資料信息;
- 用戶名儒洛;
- 密碼
- 頭像
- comment:評論數(shù)據精耐,管理用戶的評論信息;
- 用戶名
- 頭像
- 留言內容
- 時間
- users:用戶數(shù)據究反,管理用戶資料信息;
- 功能
- top部分:--公用的琅锻;--include
- 未登錄:logo卦停,全部說說,注冊恼蓬,登錄惊完;
- 注冊功能;跳轉注冊頁面处硬;
- 登錄功能小槐;
- 已登錄:logo,全部說說,我的說說荷辕,用戶列表 歡迎您xxx 設置
- 設置功能:
- 個人資料:跳轉文件上傳頁面凿跳;圖片上傳,圖片裁切疮方;
- 退出功能控嗜;
- 設置功能:
- 未登錄:logo卦停,全部說說,注冊恼蓬,登錄惊完;
- index頁面
- 登錄前
- 歡迎注冊:通過點擊按鈕跳轉到注冊頁面
- 歡迎登錄:直接登錄;
- 登錄后
- 左邊:頭像
- 右邊:
- 上面:歡迎你:xxx骡显;
- 留言框:
- 發(fā)布留言的按鈕疆栏;
- 登錄前
- 底部評論區(qū)
- 無論是否登錄,都有留言列表:頭像惫谤,用戶名壁顶,內容,時間石挂;
- 我的說說--必須先登錄才能看到
- 上面:頭像 xxx的個人主頁
- 下面:當前登錄者的所有留言和留言時間以及刪除按鈕
- 用戶列表
- 上面:用戶列表
- 下面:頭像和用戶名博助;
- top部分:--公用的琅锻;--include
項目制作前的準備
- 項目文件夾及文件
- MVC結構
- M:models => mongodb.js mongodb-setting.js md5.js
- V:views => pub(top.ejs,footer.ejs) cut.ejs index.ejs login.ejs mycom.ejs mycom.ejs reg.ejs upfile.ejs userlist.ejs
- C:controller => router.js package.json;
- mongoDB:數(shù)據庫
- public:靜態(tài)資源目錄险污,css,img,js
- avator:頭像存儲目錄痹愚,設置靜態(tài)資源目錄;
- node_modules:第三方模塊存儲蛔糯;
- package.json:項目初始化文件記錄信息拯腮;
- app.js:服務器
- readme.txt:文檔信息;
- MVC結構
- 安裝的第三方模塊
- express mongodb ejs silly-datetime gm formidable express-session
- 靜態(tài)資源文件
- bootstrap jQuery
- 截圖的css和js文件
項目制作
-
思路
- 首頁的制作蚁飒,index.ejs文件的制作
- 頁面展現(xiàn)前动壤,必須設置靜態(tài)資源目錄,設置在public目錄下淮逻;用于引入ico圖標和js,css文件琼懊;
- 渲染頁面前設置ejs模板引擎阁簸;
- 發(fā)送請求:地址欄發(fā)送get請求,請求"/forum"哼丈,然后render渲染首頁启妹;
- 提取公共部分,頭部和尾部放在top.ejs和footer.ejs文件中醉旦,放在views文件在pub中饶米,通過include引入;
- 頁面頂部搭建好未登錄狀態(tài)下的靜態(tài)頁面车胡;
- 注冊功能
- 通過top頂部中的注冊按鈕檬输,發(fā)送get請求,請求:"/reg"匈棘,渲染頁面丧慈;
- 制作靜態(tài)頁面,通過ajax發(fā)送post請求主卫,提交注冊數(shù)據伊滋;
- 點擊注冊頁面中的提交按鈕,ajax發(fā)送post請求队秩,請求:"/doreg",提交數(shù)據笑旺;
- 管理器router.js中接收數(shù)據,用formidable接受post請求發(fā)送的數(shù)據馍资;通過mongodb封裝的函數(shù)筒主,插入到數(shù)據庫的users集合中;
- 插入的數(shù)據有:用戶名,密碼(加密后的密碼)鸟蟹,默認的圖片地址乌妙;
- 注意:在插入數(shù)據庫之前,必須在數(shù)據庫中查找username是否存在建钥,如果不存在藤韵,在插入;
- 插入成功后熊经,必須設置session泽艘;設置session的login,username,imgpath;
- 注冊成功后,跳轉到首頁镐依;
window.location.href="/forum"
;
- 登錄功能
- 通過top頂部的登錄按鈕匹涮,發(fā)送get請求,請求:"/login";渲染頁面
- 制作靜態(tài)頁面槐壳,通過ajax發(fā)送請求然低,請求:"/dologin";提交登錄數(shù)據
- 服務器接收數(shù)據后,通過db.find()查找是否存在數(shù)據,當數(shù)據存在的時候雳攘,再校驗密碼带兜;
- 校驗成功后,登錄成功吨灭,但是要設置session鞋真,其中imgpath為數(shù)據庫中存的值;
- 未登錄和已登錄狀態(tài)下沃于,頁面的顯示不同
- 通過ejs中的花式賦值涩咖,設置條件判斷
- 判斷條件是:session設置中的login的賦值;
- 未登錄狀態(tài)繁莹,session中的login不存在檩互,或者被賦值為false(在退出登錄時);登錄狀態(tài)下咨演,賦值為true;
- 所以通過條件判斷闸昨,來決定那部分元素顯示,那部分元素隱藏薄风,通過curent的設置饵较,來讓那個元素點亮;
- 要求:只要涉及到login的值的情況下遭赂,在渲染頁面時循诉,必須傳參;
- 退出登錄功能
- 點擊設置中的退出登錄按鈕撇他,通過a標簽中的href發(fā)送get請求茄猫,請求"/logout";
- 服務器中設置session的值,將login設置為false困肩,將username設置為空划纽;
- 通過res.redirect()重定向刷新首頁;如:
res.redirect("/forum")
;
- 修改頭像—上傳頭像文件
- 點擊設置中的修改頭像按鈕锌畸,通過href發(fā)送get請求勇劣,請求"/upfile",然后渲染頁面;
- 渲染頁面之前潭枣,要進行判斷比默,判斷當前狀態(tài)是否為登錄狀態(tài),即session.username是否存在卸耘;如果存在退敦,再渲染頁面粘咖,傳入參數(shù)蚣抗,如果不存在,提醒去登錄;
- 頁面渲染后翰铡,通過上傳按鈕的點擊事件钝域,發(fā)送ajax的post請求,請求:"/doupFile"锭魔,上傳文件例证;
- 注意:
1)此時form表單中設置enctype為"multipart/form-data";用于大文件上傳迷捧;
2)ajax上傳file文件织咧,data設置必須為:data:new FormData($('#formid')[0])
,這樣才能在服務器端通過files來獲取文件信息伐割,與form表單提交相同痘括;
- 注意:
- 上傳圖片后乱陡,通過fs中的rename來修改上傳到文件路徑和名稱馋没;然后放在avatar目錄下粱玲;
- 上傳成功后上忍,先不對數(shù)據庫中的圖片地址進行修改怒见;
- 在前端中ajax的success函數(shù)中跳轉切圖頁面杆查;
- 切圖功能
- 通過upfile.ejs中ajax請求成功后的success函數(shù)中搂抒,跳轉頁面發(fā)送請求艇搀;請求"/cut";渲染頁面
- 在渲染頁面前求晶,對session.username進行判斷焰雕;確保在登錄狀態(tài)下,才能進行裁切芳杏;
- 注意:在渲染切圖頁面時淀散,需要傳參,此時的imgpath不能使用session.imgpath蚜锨,因為此時需要裁切的是剛剛上傳上來的圖片档插,不是數(shù)據庫中的原圖片;所以此時需要拿到上傳功能中的圖片新名稱亚再,所以需要設置全局變量郭膛;
- 在頁面設置中,通過靜態(tài)目錄打開avatar目錄下剛剛上傳后的圖片氛悬;
- 引入切圖頁面的所有文件css和js则剃,放入到public目錄下;引入文件如捅;
- 裁切功能
- 點擊截圖按鈕棍现,通過ajax發(fā)送get請求,請求:"/docut"镜遣;提交裁切的數(shù)據己肮;
- 裁切數(shù)據通過data設置,主要拿的是,裁切后圖片的寬谎僻,高娄柳,左邊距,上邊距艘绍;
- 考慮到赤拒,上傳的圖片大小都不同,所以需要設定顯示在頁面上的寬度诱鞠,所以需要算出比例挎挖,讓參數(shù)乘以對應比例后,才能對原圖片裁切航夺,否則肋乍,尺寸會出錯;
- 服務器端拿到數(shù)據后敷存,通過gm模塊來對原圖進行裁切墓造,然后再放在原來的路徑下;
- 裁切成功后锚烦,對當前用戶在數(shù)據庫中的imgpath進行修改觅闽,通過username進行查找,設置imgpath值涮俄,需注意的是蛉拙,使用$set來進行部分設置,否則彻亲,就會被全部覆蓋孕锄;
- 當數(shù)據庫中imgpath修改成功后,必須對session中的imgpath值進行修改苞尝;此時證明切圖成功畸肆;
- 切圖成功后,在success中宙址,跳轉回首頁轴脐;
- 提交留言功能
- 在首頁中,制作留言頁面抡砂;通過判斷l(xiāng)ogin的值大咱,在當?shù)卿洜顟B(tài)下,使其顯示注益;
- 點擊提交按鈕碴巾,發(fā)送ajax請求;請求:"/docom",服務器端獲取上傳的數(shù)據丑搔,然后插入到數(shù)據庫的comments集合中厦瓢;
- 插入的數(shù)據:用戶名提揍,圖像名稱,內容旷痕,時間戳碳锈;參數(shù)通過session來拿username和imgpath顽冶;
- 插入數(shù)據成功后欺抗,在success中,刷新首頁强重;
- 留言板制作
- 頁面無論在登錄還是在未登錄的狀態(tài)下绞呈,首頁刷新后,就會顯示留言信息间景;
- 需要對數(shù)據進行排序和分頁顯示佃声;
- 獲取所有數(shù)據的總個數(shù),用于分頁倘要;
- 頁面一刷新圾亏,就通過ajax發(fā)送get請求,請求:"/getcount"封拧,獲取數(shù)據總個數(shù)志鹃,返回success中;
- 設置變量pageamount泽西,每頁展示多少個數(shù)據曹铃,然后計算出頁碼個數(shù);
- for循環(huán)捧杉,通過字符串拼接陕见,在DOM插入分頁;
- 制作頁面結構味抖;封裝一個函數(shù)getData(n),其中n的值為page值评甜;即哪一頁;
- 函數(shù)中通過ajax發(fā)送請求仔涩,請求:"/getcom",獲取指定的數(shù)據蜕着,通過傳入page和pageamount來獲取指定頁碼的數(shù)據,獲取到的數(shù)據為一個數(shù)組红柱,每一個元素均為一個對象承匣,遍歷數(shù)組,通過字符串拼接插入DOM中锤悄;
- 函數(shù)需要傳實參n韧骗,來獲取第幾頁的數(shù)據,從0開始零聚,n為0袍暴,則代表第1頁些侍;
- 在頁面結構制作中,設置了一個顯示詳情的按鈕政模;
- 點擊按鈕時岗宣,彈出模態(tài)框,顯示詳細信息淋样;
- 注意:模態(tài)框中的點擊按鈕中的
data-target
設置的值必須與彈出框的id值一致耗式,并且要求,每條數(shù)據的id值不能相同趁猴;可以使用數(shù)據自己的"_id"值刊咳;
- 首頁加載,默認顯示第一頁的數(shù)據儡司,第一個分頁點亮
- 在插入DOM后娱挨,獲取所有分頁元素,添加類名active捕犬,來點亮第一個跷坝;注意:jQuery中無DOM映射,所以需要在頁面DOM元素改變后碉碉,重新獲取元素柴钻;
- 調用函數(shù)getData(),傳入實參為0誉裆,即顯示第一頁數(shù)據顿颅;
- 點擊頁碼,顯示該頁碼數(shù)據
- 對每個頁碼元素添加點擊事件足丢;
- 點擊事件觸發(fā)粱腻,通過index()獲取該點擊元素的索引值,然后作為實參斩跌,調用getData()函數(shù)绍些,然后獲取該頁碼的數(shù)據,插入到頁面中耀鸦,進行更新柬批;然后給該元素添加active類名,將其點亮袖订,其余的元素刪除類名氮帐;
- 我的說說頁面
- 點擊top中的我的說說按鈕,通過href發(fā)送get請求洛姑,請求:"/mycom";然后渲染頁面上沐;
- 渲染頁面時判斷是否在登錄狀態(tài);
- 渲染頁面時楞艾,需要傳入參數(shù):login,username,imgpath,current;
- 頁面加載后参咙,通過ajax發(fā)送get請求龄广,請求:"/getmycom",獲取該用戶的所有數(shù)據;
- 獲取數(shù)據后蕴侧,遍歷插入DOM中顯示择同;
- 我的說說頁面中每條數(shù)據后,設置了刪除按鈕净宵;
- 點擊刪除按鈕敲才,通過href發(fā)送get請求,請求:"/delete/${this._id}"塘娶;
- 通過每條數(shù)據唯一的"_id"值归斤,來發(fā)送請求痊夭;
- 在服務器端設置get請求的地址為:"/delete/:id";代表id的取值可以是任何值刁岸;
- 通過req.params.id來獲取請求地址中的id值,也就是獲得每條數(shù)據的"_id"值她我;
- 通過db.deleteMany()函數(shù)查找刪除數(shù)據虹曙,在查找數(shù)據時,需要引入objectId模塊番舆,來處理id值酝碳;
- 查找的數(shù)據:
{_id:objectId(req.params.id)}
; - 刪除成功后,在前端頁面彈出刪除成功恨狈,通過window.location.href跳轉刷新我的說說頁面疏哗;
- 用戶列表頁面
- 用戶列表在未登錄狀態(tài)下,就顯示禾怠,所以返奉,在渲染頁面時,無需判斷是否在登錄狀態(tài)吗氏;
- 點擊top中的用戶列表按鈕芽偏,發(fā)送get請求,請求:"/userlist",渲染頁面弦讽,傳入參數(shù)污尉;
- 頁面加載后,通過ajax發(fā)送get請求往产,請求:"/getuserlist"被碗,獲取users集合下的數(shù)據;
- 數(shù)據獲取后仿村,遍歷插入DOM中锐朴,頁面中需要username和imgpath數(shù)據;
- 404頁面
- 設置use請求奠宜,請求地址為"/"包颁,則在輸入地址錯誤時瞻想,渲染404頁面;
- 首頁的制作蚁飒,index.ejs文件的制作
-
知識點:
- session的設置娩嚼,在整個項目中蘑险,起到決定性作用,登錄狀態(tài)與未登錄狀態(tài)下岳悟,通過判斷session.login的值佃迄,來在ejs中進行條件判斷,然后讓哪些元素顯示贵少;
- 通過獲取session.username的值呵俏,就能獲取到當前登錄狀態(tài)下的用戶名,進而去查找數(shù)據滔灶;
- 所有的操作普碎,就是在刷新首頁,當首頁刷新時录平,會通過login的值麻车,來進行判斷,然后顯示頁面元素斗这;進而展現(xiàn)出登錄與未登錄的狀態(tài)动猬;
- 在注冊和登錄的代碼中,無論是插入數(shù)據還是校驗數(shù)據表箭,當成功后赁咙,都對session的login,username,imgpath進行重新賦值,然后免钻,發(fā)送請求"/forum"彼水,也就是刷新首頁,通過被修改后的值伯襟,來判斷哪些元素顯示猿涨,進而呈現(xiàn)出哪種狀態(tài);
- 在top頂部導航中控制哪個元素被點亮姆怪,通過設置current參數(shù)叛赚,渲染頁面時,傳入current值稽揭;
- 在前端中發(fā)送請求俺附,刷新頁面,用到的代碼:
window.location.href="/forum"
- 在服務器端發(fā)送請求溪掀,刷新頁面事镣,用到的代碼:
res.redirect("/forum")
; - 上傳文件時揪胃,ajax發(fā)送post請求璃哟,file文件參數(shù)上傳時氛琢,data必須設置為
data:new FormData($('#formid')[0])
,不能用key=val鍵值對設置随闪,具體使用請見鏈接:Ajax通過FormData上傳文件 - avatar文件夾中存放的時數(shù)據庫中存的頭像名稱所對應的文件阳似;所以需要設置靜態(tài)資源目錄,才能展現(xiàn)這些圖片铐伴;
- 設置靜態(tài)資源目錄:
app.use("/avatars",express.static("./avatar"));
含義是撮奏,在img中src設置時,需要將文件放在avatar目錄下当宴,但是在設置時畜吊,需要在前面加上"/avatars",然后加上目錄下的相對路徑;
- 設置靜態(tài)資源目錄:
- icon圖標的設置:
<link rel="icon" href="/img/icon.jpg">
,靜態(tài)資源目錄下的相對路徑户矢;
-
注意點:
- 只要進行頁面渲染時玲献,render中就必須傳參;否則逗嫡,頁面不會正常展現(xiàn)青自;
- 注冊和登錄時株依,都適用post請求驱证,安全性更高,get請求恋腕,會將用戶名和密碼顯示在地址欄中抹锄,不安全;
- 上傳文件和截圖兩個頁面在渲染時荠藤,必須對session.username進行判斷伙单,確定在登錄狀態(tài)下,才能進行哈肖,否則吻育,不能進行,提醒登錄淤井;
- 頭像在數(shù)據庫中存的是文件名布疼;所以在顯示圖片時,只需將數(shù)據庫中的對應地址拿出來币狠,放在src中游两;但是需注意的是,要設置靜態(tài)資源目錄漩绵,要跟use中前面設置的地址一直贱案,并將其放在后面的目錄下,在引用時止吐,前面必須加前綴宝踪;如此項目中侨糟,設置靜態(tài)資源時,設置了"/avatar"瘩燥,在引用時粟害,必須加此前綴,后面加目錄下的相對路徑颤芬;
- 上傳文件后悲幅,不對數(shù)據庫中的imgpath進行修改,必須在截圖功能成功后站蝠,在能對數(shù)據庫進行修改汰具;為了防止當上傳文件后,不對文件進行裁切菱魔,就直接回到首頁留荔,然后圖片會顯示原來的尺寸,頁面會很難看澜倦,所以聚蝶,只要不修改數(shù)據庫,也不能修改session中的imgpath藻治,頁面中就不會顯示剛剛上傳的圖片碘勉;
- 上傳文件的功能:圖片在上傳時,先上傳到uploads文件夾中桩卵,只有在裁切圖片后验靡,才能放在avatar文件夾下,圖片在加載時雏节,靜態(tài)資源目錄也要設置在avatar文件夾下胜嗓;注:設置靜態(tài)資源路徑時,不要只設置為"/"钩乍,要設置特定的路徑"/avatar"辞州;
- 在截圖功能中,需要打開圖片寥粹,所以必須賦值上傳功能中的圖片新名字变过;這樣才能拿到新圖片,不能設置session中的imgpath排作,這樣拿到的是修改頭像之前的圖片牵啦;
- 在數(shù)據中的頁面詳情設置中,使用了模態(tài)框妄痪,在設置模態(tài)框中的點擊按鈕的
data-target
的值時哈雏,要求其必須與彈出框的id值一致,并且要求每條數(shù)據的id值不能相同;可以使用數(shù)據自己的"_id"值裳瘪; - 在上傳的文件修改名字時土浸,使用fs.rename時,newpath設置時彭羹,是通過"./"來獲取根目錄黄伊,然后在設置相對路徑;
- 在使用gm()截圖時派殷,路徑也是通過"./"來獲取根目錄还最,然后設置相對路徑找文件;
-
項目改善
- 問題:在上傳文件后毡惜,會將avatar目錄下的原圖片修改掉拓轻,所以不管改不改數(shù)據庫,或者是否該session.imgpath经伙,此時session.imgpath有可能是新的名字了扶叉;所以在刷新首頁的時候,上傳的文件還會顯示帕膜,頁面會難看枣氧;
- 改善:
- 上傳文件的存儲目錄,必須設置一個新的目錄垮刹,作為中間目錄达吞,上傳文件修改名字后,放在此目錄中危纫;就不會對avatar中的原圖片進行覆蓋宗挥,不截圖的情況下,還會顯示原來的圖片种蝶;
- 截圖功能中,需要將上傳的文件進行打開裁切瞒大,可以在設置一個靜態(tài)資源目錄螃征,專門存儲上傳的文件,然后再cut.ejs中打開上傳文件時透敌,就可以寫新設置的靜態(tài)資源目錄下的相對路徑了盯滚;
- 在服務器端切圖時,gm中的原地址酗电,寫上傳文件存儲地址魄藕,注意此時通過"./"拿到根目錄,然后進行相對路徑查找撵术,跟靜態(tài)資源目錄的查找不同背率;在裁切完后,write中的路徑需要存儲在avatar目錄中;覆蓋原來圖像寝姿;
- 此時就完成了修改圖像的功能交排,然后再修改數(shù)據庫,修改數(shù)據庫成功后饵筑,必須重新設置session.imgpath值埃篓;
- 改善:
- 問題:在切圖后,會修改圖片根资,進而修改數(shù)據庫中的圖片地址架专,但是在此數(shù)據庫中兩個集合中,都存了圖像的地址玄帕,如果需要更改胶征,兩個集合都需要修改;所以會出現(xiàn)問題桨仿;
- 改善:在users集合中睛低,不再插入 圖片地址信息,在頁面渲染時服傍,都會傳入imgpath值钱雷,此時的值為session設置的值,所以吹零,在comments數(shù)據庫中imgpath數(shù)據修改后罩抗,需要重新設置session中的imgpath值;
- 問題:在上傳文件后毡惜,會將avatar目錄下的原圖片修改掉拓轻,所以不管改不改數(shù)據庫,或者是否該session.imgpath经伙,此時session.imgpath有可能是新的名字了扶叉;所以在刷新首頁的時候,上傳的文件還會顯示帕膜,頁面會難看枣氧;