Express API 總結(jié)

express是一款簡(jiǎn)單的web開(kāi)發(fā)應(yīng)用框架,這里主要是一些主要api的使用方法和總結(jié)記錄。

中間件

首先,express的靈魂就是中間件,它能影響到使用者的開(kāi)發(fā)思路,能將請(qǐng)求響應(yīng)的流程拆分成不同模塊進(jìn)行開(kāi)發(fā),然后app.use調(diào)用(可以一個(gè)或多個(gè))。這就是其中間件的的基本特征,然后編寫(xiě)一個(gè)中間件也比較簡(jiǎn)單:

var express = require('express')
var app = express()

var myLogger = function (req, res, next) {
  console.log('LOGGED')
  next()
}
var Login = function (req, res, next) {
  // do something for login
  next()
}

app.use(myLogger)
app.use(Login)

app.get('/', function (req, res) {
  res.send('Hello World!')
})

app.listen(3000)

上面例子是摘自官方文檔的一小段代碼。首先app.use()就是調(diào)用中間件(myLogger,Login)的關(guān)鍵,然后(myLogger,Login)函數(shù)里有個(gè)next回調(diào)函數(shù),當(dāng)調(diào)用它時(shí)可以執(zhí)行下一個(gè)中間件。不過(guò)也可以不寫(xiě)(表示最后一個(gè)中間件)或者提前使用res.end()之類(lèi)的提前結(jié)束。

接下來(lái)是關(guān)于API的一些記錄,從express和其子實(shí)例,request,response,router五個(gè)主要API入手。

express

導(dǎo)入的express模塊可以直接執(zhí)行,然后生成子實(shí)例。但express本身也帶有一些方便的方法:

  • express.json()
  • express.raw()
  • express.Router() // 陌生,這里不記錄
  • express.static()
  • express.text()
  • express.urlencoded()

當(dāng)一個(gè)請(qǐng)求過(guò)來(lái)時(shí),其參數(shù)有可能放在請(qǐng)求主體里,可以通過(guò)request的body、query、params的屬性來(lái)訪(fǎng)問(wèn)這些參數(shù)。但如果請(qǐng)求方法是post,且參數(shù)是通過(guò)JSON,XML或者就一段文本方式放在主體里傳過(guò)來(lái),直接拿req.body反而獲取不到,需要通過(guò)request的on監(jiān)聽(tīng)data事件,例如

app.post("/a", (req, res, next) => {
    req.on("data", (chunk) => {
        console.log(chunk.toString())
    })
    next()
})

然后express就提供了一些內(nèi)置的中間件,就例如express.json()、express.raw()、express.text(),甚至有解碼用的express.urlencoded(),只需在自己代碼之前用就可以了。

 app.use(express.json())
 app.use((req,res,next)=>{
   // 自己代碼
   next()
 })

express.static()提供了一個(gè)比較方便的方法供請(qǐng)求靜態(tài)資源,他接受一個(gè)root路徑和一個(gè)對(duì)象參數(shù),當(dāng)訪(fǎng)問(wèn)者訪(fǎng)問(wèn)“/root/xxx.html”時(shí),express會(huì)幫我們自動(dòng)響應(yīng)響應(yīng)的“/root/xxx.html”文件,如果沒(méi)有就會(huì)調(diào)用next回調(diào)進(jìn)入下一中間件。

express子實(shí)例

感覺(jué)這個(gè)也可以當(dāng)做是express來(lái)記錄,但文檔也將其分開(kāi),那這里也分開(kāi)記錄(部分)。

var express = require('express')

var app = express() // the main app
var admin = express() // the main app

這里用app替代express子實(shí)例的叫法

app有兩個(gè)屬性locals、mountPath,一個(gè)mount事件,十九個(gè)方法。

app.locals作為局部變量可存儲(chǔ)對(duì)象,這個(gè)能一直在應(yīng)用程序的整個(gè)生命周期中保持不變,app存在局部變量也存在,人在塔在!

app.mountpath可以返回不同路徑模式的路徑數(shù)組,例如app和admin同時(shí)用get監(jiān)聽(tīng)“/”路徑,那么app.mountpath將可以有效區(qū)別request的路徑,這和request.baseurl的有點(diǎn)不同。

app.on('mount',callback(parent))也是在兩個(gè)子實(shí)例情況下應(yīng)用,當(dāng)mount事件安裝在父應(yīng)用程序上時(shí),該事件將在子應(yīng)用程序上觸發(fā)。父應(yīng)用程序?qū)鬟f給回調(diào)函數(shù)。

var admin = express()
var app= express()

admin.on('mount', function (parent) {
  // 這里將被執(zhí)行
  console.log('Admin Mounted')
  console.log(parent) // refers to the parent app
})

admin.get('/', function (req, res) {
  res.send('Admin Homepage')
})

app.use('/admin', admin)

app.get()有兩個(gè)用法,當(dāng)你傳一個(gè)字符串參數(shù)時(shí),它會(huì)返回上面所說(shuō)的局部變量locals的相應(yīng)值。當(dāng)兩個(gè)參數(shù)(一個(gè)字符串和一個(gè)回調(diào)函數(shù)),它就是監(jiān)聽(tīng)相應(yīng)路徑的get請(qǐng)求方法,這是這個(gè)方法基本和post,put,patch,delete,all,METHOD類(lèi)似的。

app.param([name], callback)是一個(gè)有趣的方法,param里如果存在相應(yīng)的[name]屬性,則執(zhí)行后面的callback。

app.set(name, value)比較特殊,可以存儲(chǔ)一些自定義的鍵值對(duì),但app也提供了一些特別的設(shè)置(例如:env,etag,jsonp callback name),可以前往官網(wǎng)查看。

app.use([path,] callback [, callback...])很常見(jiàn)也很重要,第一個(gè)參數(shù)是路徑,之后的就是回調(diào),當(dāng)匹配到相應(yīng)路徑執(zhí)行后面的回調(diào),當(dāng)然是按照先后順序,多個(gè)回調(diào)里的函數(shù)順序比下一個(gè)中間件執(zhí)行時(shí)機(jī)早。callback里有四個(gè)參數(shù),形式:

app.use(function ([err,] req, res, next) {
  console.error(err.stack)
  res.status(500).send('Something broke!')
})

如果使用四個(gè)參數(shù),那么它是一個(gè)錯(cuò)誤處理中間件,否則3個(gè)是常規(guī)中間件.

Request

request包含了app作為其屬性,所以通過(guò)req.app來(lái)訪(fǎng)問(wèn)app的所有權(quán)限。

request.baseUrl可以獲得app.use監(jiān)聽(tīng)的路徑。

request.body可以獲取請(qǐng)求存儲(chǔ)在主體的參數(shù),不過(guò)正常情況下都是undefined,所以才需要使用諸如express.json()或的正文解析中間件時(shí)進(jìn)行填充express.urlencoded() 。

request.cookies可以獲取請(qǐng)求里的cookie,如果沒(méi)有返回空對(duì)象。

request.hostname可以獲取域名,如果你要用得上的話(huà)。

request.query和request.params也可以獲取參數(shù),但query只需要在路由上寫(xiě)?a=1&b=2之類(lèi)的附加值就可以獲得,而params需要請(qǐng)求固定設(shè)置或路由上設(shè)置/user/:name之類(lèi)的。

request有一些方法,

req.accepts(types),根據(jù)請(qǐng)求的AcceptHTTP標(biāo)頭字段檢查指定的內(nèi)容類(lèi)型是否可接受,以下三個(gè)方法基本也是在設(shè)置headers的頭部字段

req.acceptsCharsets(charset [,...]),

req.acceptsEncodings(encoding [,...]),

req.acceptsLanguages(lang [, ...])

然后也可以通過(guò)req.get(type)來(lái)獲取某個(gè)字段的值,或者req.is(value)判斷該value是不是請(qǐng)求過(guò)來(lái)“Content-Type”的值。

Response

首先說(shuō)屬性,簡(jiǎn)稱(chēng)Response為res

res也可以訪(fǎng)問(wèn)app,也有個(gè)loacals屬性(但只能在本次請(qǐng)求周期使用)

res有21個(gè)方法,這里挑幾個(gè)常用的記錄:

append(field [, value])用于設(shè)置頭部的屬性和值;

cookie(name, value [, options])用于設(shè)置cookie;

clearCookie(name, [, options])用于清除cookie;

res.download(path [, filename] [, options] [, fn])用于響應(yīng)用戶(hù),下載指定的靜態(tài)文件等;

res.end([data] [, encoding])結(jié)束響應(yīng),和node的一致;

res.format(object)這個(gè)根據(jù)請(qǐng)求的accept字段值不同做不同的響應(yīng);

res.send([body])用于發(fā)送響應(yīng),但能發(fā)送很多類(lèi)型的數(shù)據(jù),除了文件

res.sendFile(path [, options] [, fn])和send相似,但傳送文件,注意path是絕對(duì)路徑

res.status(code)用于發(fā)送狀態(tài)碼,例如403等

res.append('Set-Cookie', 'foo=bar; Path=/; HttpOnly')
res.cookie('rememberme', '1', { expires: new Date(Date.now() + 900000), httpOnly: true })
res.clearCookie('rememberme')
res.download('/report-12345.pdf')
res.format({
  'text/plain': function () {
    res.send('hey')
  },

  'text/html': function () {
    res.send('<p>hey</p>')
  },

  'application/json': function () {
    res.send({ message: 'hey' })
  },

  'default': function () {
    // log the request and respond with 406
    res.status(406).send('Not Acceptable')
  }
})

Router

Router的用法基本和app.use監(jiān)聽(tīng)某些路由一樣,有五個(gè)方法:

  • router.all()
  • router.METHOD()
  • router.param()
  • router.route()
  • router.use()
    但從用法上感覺(jué)和app.xxx沒(méi)什么區(qū)別!
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

友情鏈接更多精彩內(nèi)容