寫前端的朋友不知道如何拓展自己在后端的能力徽龟,那么nodejs是你的不二選擇,廢話不多說镶摘,直接進入正題。
? ? 這里我演示的是nodejs+mysql岳守,別的數(shù)據(jù)庫也類似凄敢。
? ? 首先我們需要做兩件事,下載nodejs和mysql安裝湿痢,這些基本知識略過涝缝。
? ? 接著新建一個文件夾,在此文件夾下打開cms,或者vscode的終端譬重,輸入node init初始化一個項目俊卤,輸入一些基本信息。
? ? 然后我們我們還需要安裝以下包到--save下
express和mysql這兩個包是最主要的害幅,稍后再講其他包的作用。
在這里我要闡明一個事實岂昭,這里的mysql是操作mysql數(shù)據(jù)庫的一個js插件以现,并不是數(shù)據(jù)庫軟件,npm下載的包都是一些js的插件包约啊。
好了邑遏,接下來和我一步步向下操作就可以了。
在文件夾下新建一個index.js文件恰矩,當然別的名字也可以记盒,這個文件是你整個程序的入口。
鍵入以下代碼:
80代表的是你的端口號外傅,然后在終端或者cms輸入node index.js纪吮,在瀏覽器里打開localhost就可以看到了,或者127.0.0.1也行萎胰,如果是別的端口號需要加上端口號碾盟,當然現(xiàn)在是什么也沒有,因為我們還沒有寫接口技竟。
接下來我們寫一個get接口冰肴,返回一個‘hello world’字符串
res.json這個方法是以json對象的形式返回去,還有以下方法
res.send以頁面的方式返回去
res.download以文件的方式返回去,前端請求會下載此文件
別的方法這里就不在一一闡明了熙尉,可以打出res.然后使用vscode的語法提醒查看下面的方法即可联逻,或者查看文檔看解釋。
接下來我們返回一個頁面:
可以看到localhost頁面上出現(xiàn)了我們預(yù)期的結(jié)果
到了這里想必你們已經(jīng)發(fā)現(xiàn)問題了检痰,我每次改動一下都要重新跑程序包归,這不符合人體工程學(xué),說的一點沒錯攀细,我無法容忍箫踩,你萌呢?
想必你們在前面也發(fā)現(xiàn)了pageage.json里有這么一句話
scripts的作用就是自己定義腳本命令谭贪,在這下面定義的所有命令都可以使用npm run xxx來運行境钟,可以省略run。里面運行的應(yīng)該是node index.js才對俭识,但是這里我們使用了一個插件慨削,hotnode,這個插件可以讓你的node程序熱更新套媚,要全局安裝這個插件缚态,不然找不到命令。
npm install -g hotnode
然后我們就可以npm start運行我們的程序了堤瘤,所有基于node的程序跑起來都是兩步玫芦,npm install,安裝所有插件,npm start運行程序本辐,如果跑不起來桥帆,那么這個項目一定不是一個好項目,我通常如此告誡我的弟子慎皱,我們一定要站在巨人的肩上老虫。
做到這里,我們接下來就可以愉快的開發(fā)了茫多。
接下來我們試試post方法
post不支持瀏覽器直接訪問祈匙,這個時候要用postman軟件
依然符合我們的預(yù)期。
可以把路徑改為/login天揖,/test進行嘗試夺欲,這里就不再演示了。
也可以試試app.all方法今膊,這個方法支持所有請求方式洁闰,不必每個請求都寫好幾遍了。
想必大家已經(jīng)想到了万细,我要做登錄攔截難道每個接口里都要寫一遍嗎扑眉。
答案是當然不用的纸泄,接口的第一個參數(shù)可以用正則表達,我們這么寫:
我們使用*來匹配所有路徑腰素,這個時候請求test,會先經(jīng)過*聘裁,被*攔截返回了***,
我們可以在內(nèi)部判斷來進行操作:
如果未登錄弓千,返回未登錄衡便,否則,繼續(xù)向下匹配洋访,回調(diào)函數(shù)接收三個參數(shù)镣陕,最后一個是next,繼續(xù)向下執(zhí)行,*路徑一定要寫在最上面姻政,不然會先被test捕捉到呆抑,test沒有執(zhí)行next,*就會捕捉不到請求。
這時候就可以設(shè)置login的值來看路徑localhost/test下的返回值了汁展。
那么有參數(shù)的情況呢鹊碍,我們先引入一下中間件,如果沒有安裝可以先npm安裝
接下來我們請求一下
食绿?后面的表單參數(shù)會放到req.query里侈咕,路徑上的參數(shù)會放到req.params里,json參數(shù)會放到req.body里器紧,可以任意選擇一種參數(shù)傳遞即可耀销,路徑以:開頭表示此路徑作為參數(shù)的意思。
前后端聯(lián)調(diào)的時候經(jīng)常碰到跨域的問題铲汪,我們可以使用cors插件解決熊尉,
以上提到的跨域和參數(shù)都可以自己進行處理,利用路徑自己提取參數(shù)桥状,在*路徑的請求的請求體req里自己加上跨域允許的header,但我希望你們可以使用插件硝清,保證代碼的簡潔性辅斟,同時
我經(jīng)常告訴我的弟子,我們一定要站在巨人的肩上芦拿。
好了士飒,接下來我們開始連接數(shù)據(jù)庫,從數(shù)據(jù)庫里拿一條數(shù)據(jù)出來返回給前端蔗崎。
引入mysql插件酵幕,我們先在mysql里新建一個表students,存入以下數(shù)據(jù):
然后使用mysql插件連接數(shù)據(jù)庫
option里都是連接數(shù)據(jù)庫的基本配置缓苛,更多參數(shù)可以查看文檔芳撒,我們請求一下localhost/login看看
真的返回了我們存在數(shù)據(jù)庫的數(shù)據(jù),我好激動啊,大業(yè)終于完成了笔刹。
是的芥备,conn.query就是執(zhí)行一條sql語句,在回調(diào)函數(shù)里返回結(jié)果舌菜。
結(jié)果可以用構(gòu)造函數(shù)封裝萌壳,這樣就不用每次都寫一推沒用的字段了。
如果你在此處這樣做:
那么這個不妥的日月,第一次沒有問題袱瓮,第二次不行了,說是關(guān)閉了數(shù)據(jù)庫無法繼續(xù)查詢爱咬,因為connect()并不能重連數(shù)據(jù)庫尺借,你需要重新建立一條新連接,所以不建議使用conn.end()斷開數(shù)據(jù)庫台颠。
如果莫名其妙斷了呢褐望,我們就需要就重連機制,斷了數(shù)據(jù)庫會觸發(fā)error事件串前,我們這樣處理:
監(jiān)聽error事件瘫里,如果err.code返回了以上字符,那么我們就重新發(fā)起連接荡碾,直到連接成功谨读。
做到這里,想必大家已經(jīng)想到了坛吁,這是單線程的劳殖,并發(fā)量高的時候會不會頂不住,會的拨脉,所以我們要上連接池哆姻。
連接池與連接相似,做以下處理:
建立連接池比連接多了幾個參數(shù)玫膀,這里羅列了常用的三個矛缨,其它參數(shù)可以查看文檔。這個時候我們使用連接池處理請求帖旨。conn.release()的意思是釋放連接池的意思箕昭,用完就要釋放給別的請求使用,也可以直接使用連接池解阅,具體區(qū)別我還不知道落竹,我猜應(yīng)該是直接使用連接池就是這個線程專門為這個請求服務(wù),不用別的也不釋放货抄,可以用于常用接口述召,可以減少取連接池的操作朱转。
做到這里我們大部分工作已經(jīng)做完了,想必大家一定又想到了什么桨武,我如果有一千個接口肋拔,難道要在一個文件里寫一千個嗎。
這當然是不妥的呀酸,比較難維護凉蜂,所以我們要拆分模塊,使用express.Router()這個api性誉。
我們將連接數(shù)據(jù)庫的文件單獨抽離
導(dǎo)出常用的pool,Result,router,app模塊窿吩,然后在子模塊:
然后在入口:
看看是不是簡潔多了,要注意一點错览,引入的子模塊要放到全局監(jiān)聽*的下面纫雁,不然又會無法匹配到*,app.use的第一個參數(shù)代表下發(fā)到那個目錄倾哺,內(nèi)部子模塊的/相當于app.use的第一個參數(shù)轧邪,接下來請求一下/和/login試試吧。
我完事兒了羞海,你萌呢忌愚?