Alpha Camp「2-3 middleware實作練習」技術記錄
2021-05-23 12:53 Express JavaScript
總結
在本作業中實作的相關功能:
- 透過 Express middleware 偵測發送給
localhost:3000
的請求 - 將每一筆對
localhost:3000
的請求(request)時間、方法、路由與回應時間輸出到終端上;形式如:2021-05-23 13:00:20 | GET from / | total time: 117ms
- 將以上記錄寫入純文字檔案中,並使用者可下載此份檔案
- 專案 GitHub:tzynwang/ac_assignment_2-3_middleware
環境
node: 12.20.2
express: 4.17.1
express-handlebars: 5.3.2
os: Windows_NT 10.0.18363 win32 x64
筆記
專案結構
├─ requestLogs
| └─ requestLogs.txt
├─ scripts
| ├─ logRequest.js
| └─ saveToFile.js
├─ views
| ├─ layouts
| | └─ main.handlebars
| └─ index.handlebars
└─ app.js
requestLogs/requestLogs.txt
:記錄每一次請求的文字檔案scripts/logRequest.js
:記錄每一次請求的日期、時間、方法與路由,除了輸出到終端外,也會呼叫saveToFile()
來將以上內容寫入檔案中scripts/saveToFile.js
:負責寫入檔案的動作views
資料夾:提供瀏覽器介面來讓使用者與此 app 互動app.js
:載入 middleware,並根據路由給予不同的回應
app.js 內容
第 11 行:Application-level middleware(app 層級的 middleware)
- The function is executed every time the app receives a request (when middleware isn’t mounted with any path).
- 出處:Express official document: Application-level middleware
- 宣告
app.use(logRequest)
讓所有的請求都會經過該 middleware
第 47-54 行:下載功能(app.post('/download', () => {...})
)
- 48 行:指定欲下載的檔案的路徑
- 49 行:取得當下時間
- 50 行:透過
.toISOString()
將 Date 物件轉換為字串,再使用.slice(0, 10)
取出日期部分 - 51 行:使用
.toLocaleTimeString()
來取 timeStart 的時間部分,因為想要取 24 小時制的時間,故option
部分加上hour12: false
指定輸出 24 小時制的時間;參考MDN: Date.prototype.toLocaleTimeString() — Using options;最後搭配.split(':').join('')
將時間字串從HH:MM:SS
的格式轉為HHMMSS
- 52 行:宣告檔案名稱格式
- 53 行:
res.download()
第一個變數為檔案路徑,第二個變數為檔案名稱;可參考Express official document: res.download()
scripts/logRequest.js 內容
第 13 行:res.locals.logs = {...}
- 路由只接受
res
或req
這兩種參數,無法透過 middleware 的next()
來傳遞變數 - 將變數賦予
res.locals
後,即可在每一個路由中透過res.locals
取出需要的值;相關概念的說明可參考以下影片(9:25 開始相關段落)
第 14 行:res.on('finish')
或res.on('close')
- Event finish: Emitted when the response has been sent. More specifically, this event is emitted when the last segment of the response headers and body have been handed off to the operating system for transmission over the network. It does not imply that the client has received anything yet. 送出回應後即觸發,不考慮客戶端是否真的有收到回應
- Event close: Indicates that the response is completed, or its underlying connection was terminated prematurely (before the response completion).
- 如果只是為計算「伺服器收到請求到發出回應」的時間的話,使用
res.on('finish')
即可
scripts/saveToFile.js 內容
- 第 4 行:
fs.appendFile()
使用方式可參考:Node.js: fs.appendFile(path, data[, options], callback)
參考文件
- Express official document:
- StackOverFlow: