隨着工作經驗的增多,通過別人的文檔來獲得幫助已經逐漸不能滿足我們的工作需求(往往是文檔寫的有延遲,而且不會更新)。這時候,就需要通過查看項目最新的代碼來保證我們工作的順利進行。正如德雷福斯模型所說,一個新手向高級新手進發的旅途上要學會不斷思考與學習。要這篇文章就是在這種狀態下誕生的。
背景:
Express是當前在Nodejs上非常火的一個輕量級框架。在Express當中,通過使用app.use來添加中間件,所謂中間件(Middleware),可以理解為一個對用戶請求進行過濾和預處理的東西,它一般不會直接對客戶端進行響應,而是將處理之后的結果傳遞下去。在Express中,分為兩種中間件,一種是內置中間件,一種是第三方中間件,如express中對靜態文件的處理就調用了它的內部中間件static:
app.use('/public',express.static(__dirname + '/public'));
可以看到,在express中,是通過app.use來調用中間件的。
在Express中,app.use
把中間件加入一個棧中,http request將觸發整個中間件鏈條,並依次執行(通過 next()
函數實現),功能類似於filter,但其作用卻大於filter,它可以動態地給req,res添加內容。更多express的內容請參見:《Node.js[5] connect & express簡介》。
具體操作:
閑話少敘,Express中對靜態文件的處理使用了express.static——對所有正常的靜態文件都直接輸出到瀏覽器了。但是在工作中我們有時對靜態文件進行一些處理,例如:express對靜態html的header編碼默認為UTF-8, 但是部分路徑下的html為GBK,這時候要讓express依據路徑來設置header頭。由於express.static是express中少有的對/pulic路徑下的route導向靜態資源文件,不調用next。我們不能在其之后添加對靜態文件的處理。那么就只有兩種實現方式:
1.自己實現靜態文件服務器
2.對express.static進行改寫
對於后者,網上並沒有相應的文檔,查閱Express文檔發現express對靜態文件的處理調用了serve-static這個組件,然后查看serve-static的代碼,發現1.7.1版本的static提供了setHeaders函數:
項目地址:https://github.com/expressjs/serve-static
setHeaders是一個允許用戶自定義設置header的方法,滿足我們的需求,大喜之下觀察它的源碼,發現只要有設置setHeaders,那么就會把setHeaders加入到Steam流中。而我們可以自己編寫setHeader來完成自己想要的功能。以下就是具體的實現,完成了對/public/lab/wwwdemo目錄下的Html頁面的header charset設置為gbk。
app.use(express.static(path.join(__dirname, 'public'),{ setHeaders:function(res,path,stat) { if(res && path.indexOf("/public/lab/wwwdemo")>-1) { res.setHeader("Content-type","text/html; charset=gbk"); } } }));
至此任務完成,盡管是一個小的任務,但是對於理解Express的原理還是有所幫助的。
參考博客: