這篇文章跟大家介紹一下node裡的靜態檔案中間件koa-static。有一定的參考價值,有需要的朋友可以參考一下,希望對大家有幫助。
相關推薦:《nodejs 教學》
在app.js裡,若想指定目前目錄為託管目錄,我們通常會這樣做:
const static=require('koa-static') const Koa=require('koa') const app=new Koa() app.use(static('.')) app.listen(8081)
koa-static 是koa(node框架)中最常用的、較成熟的靜態web託管服務中間件 ,在koa中常用於例如外鏈靜態資源(如CSS檔案):
//下载 npm install koa-static --save
//引入 const server=require('koa-static')
//使用 app.use(server('static'))//或:app.use(server(__dirname+'/static'))
總之,server裡面一定是靜態模板(相對)路徑
然後我們就可以這樣使用static目錄下的css資料夾中的xxx.css檔案了:
<link rel="stylesheet" href="css/xxx.css" />
這麼簡單?那它的原理是啥?
根據檔案後綴名設定請求頭 “Content-Type”值,使其與瀏覽器渲染相符!
就拿上面說的static說:
#尋找static/css/xxx.css
是否存在
(若存在)設定Content-Type: text/css;charset=utf-8;
透過response傳回瀏覽器
前面說了koa-static作用是☞靜態檔案託管☜ ,那肯定不只是對於CSS、JavaScript這類資源檔。
事實上,對於圖片,koa-static同樣可以用來設定 圖片快取 !就像這樣
const server=require('koa-static') const path=require('path') //path模块:设置路径信息 const staticPath=path.resolve(__dirname,'static') const staticServer=server(staticPath,{ setHeadears:(res,path,stats)=>{ if(path.indexOf(/[jpg|png|gif|jpeg]/)>-1){ res.setHeader('Cache-Control',['private','max-age=60']) } } }) app.use(staticServer);
——如果對應路徑中是jpg/GIF/png/jpeg格式的圖片,那麼就將其快取60s。
我們都知道,在express(node框架)中有一個關於靜態服務的「便捷方式」:
app.use('/teacher',express.static('/public'))
它可以指定靜態服務的「請求前綴」 ——就是指定載入相對於哪個url的靜態資源。
很明顯,這是非常實用的。我們突然想到,本文上面我們所說的koa-static都是相對於「全域 」作用的?
如何在koa中實現這個功能呢? koa為開發者提供了另一個(輔助)模組- koa-mount
const Koa=require('koa') const server=require('koa-static') const mount=require('koa-mount') const app=new Koa() app.use(mount('/teacher',server('/public')))
koa-mount是一個將中間件掛載到指定路徑的Koa中間件。它可以掛載任一Koa中間件!
前面說過,koa-static是一個中間件,所以koa-mount可以和koa-static結合,以實現和express一樣的靜態服務請求前綴的功能。
學習了上面神奇的使用方式,你有沒有想過它是怎麼實現的?
透過 npm info koa-static
,你會發現 koa-static 依賴兩個模組,分別是 debug 和 koa-send 。
找到koa-static 原始碼的index文件,其核心實作如下:
const send = require('koa-send'); //... function serve (root, opts) { //... return async function serve (ctx, next) { await next() if (ctx.method !== 'HEAD' && ctx.method !== 'GET') return if (ctx.body !== null && ctx.status !== 404) return // eslint-disable-line try { await send(ctx, ctx.path, opts) }catch (err) { if (err.status !== 404) { throw err } } } }
而經過這段程式碼,我們發現其中實作核心是send()
方法,而這是由模組koa-send 提供的!
找到koa-send的原始碼,發現其核心實作原理也是很簡單的:
if (!ctx.type) ctx.type = type(path, encodingExt) ctx.body = fs.createReadStream(path)
其中type方法是根據檔案後綴來設定 Content-Type !很實用,但是我們這裡更要關注的是另一個比較有趣的事—— koa-send的原理:
設定Content-Type ,可透過檔案後綴進行設定;
以Stream形式為ctx.body賦值
為什麼說它有趣呢?
除了它竟然也是以設定content-type為目標外,stream串流的方式一直受到業界大拿們的推崇:因為它比 fs.readFileSync
更有效率!
讓我們拿下面這段程式碼和上面koa-send 的原始碼作比較:
app.use(function(ctx){ const fs=require('fs') const result=fs.readFileSync('xxx') ctx.type=type(result, encodingExt) ctx.body=result })
其實在koa中,ctx.body的工作原理其實就和本文所說koa-static、koa-send 中間件相似:根據賦值類型來進行不同Content-type 的處理
根據body類型設定對應的Content-type
根據Content-type呼叫res.write或res.end,將資料寫入瀏覽器
關於Content-type值:
字串-又分為「text/html」和「text/plain」兩種類型(不一樣);
Buffer / Stream類型;
若不是以上任何類型,那麼應該就是JSON物件了
(原始碼中是透過typeof來判定其類型,這種技巧非常實用!
更多程式相關知識,請訪問:編程視頻!!
以上是深入淺析nodejs裡的koa-static中間件的詳細內容。更多資訊請關注PHP中文網其他相關文章!