首頁  >  文章  >  web前端  >  深入淺析nodejs裡的koa-static中間件

深入淺析nodejs裡的koa-static中間件

青灯夜游
青灯夜游轉載
2021-03-08 10:05:242349瀏覽

這篇文章跟大家介紹一下node裡的靜態檔案中間件koa-static。有一定的參考價值,有需要的朋友可以參考一下,希望對大家有幫助。

深入淺析nodejs裡的koa-static中間件

相關推薦:《nodejs 教學

細說koa-static使用

在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(&#39;koa-static&#39;)
const path=require(&#39;path&#39;)   //path模块:设置路径信息

const staticPath=path.resolve(__dirname,&#39;static&#39;)
const staticServer=server(staticPath,{
	setHeadears:(res,path,stats)=>{
		if(path.indexOf(/[jpg|png|gif|jpeg]/)>-1){
			res.setHeader(&#39;Cache-Control&#39;,[&#39;private&#39;,&#39;max-age=60&#39;])
		}
	}
})
app.use(staticServer);

——如果對應路徑中是jpg/GIF/png/jpeg格式的圖片,那麼就將其快取60s。


我們都知道,在express(node框架)中有一個關於靜態服務的「便捷方式」:

app.use(&#39;/teacher&#39;,express.static(&#39;/public&#39;))

它可以指定靜態服務的「請求前綴」 ——就是指定載入相對於哪個url的靜態資源。

很明顯,這是非常實用的。我們突然想到,本文上面我們所說的koa-static都是相對於「全域 」作用的?

如何在koa中實現這個功能呢? koa為開發者提供了另一個(輔助)模組- koa-mount

const Koa=require(&#39;koa&#39;)
const server=require(&#39;koa-static&#39;)
const mount=require(&#39;koa-mount&#39;)

const app=new Koa()
app.use(mount(&#39;/teacher&#39;,server(&#39;/public&#39;)))

koa-mount是一個將中間件掛載到指定路徑的Koa中間件。它可以掛載任一Koa中間件!
前面說過,koa-static是一個中間件,所以koa-mount可以和koa-static結合,以實現和express一樣的靜態服務請求前綴的功能。


static原理探究

學習了上面神奇的使用方式,你有沒有想過它是怎麼實現的?
透過 npm info koa-static ,你會發現 koa-static 依賴兩個模組,分別是 debug 和 koa-send 。
找到koa-static 原始碼的index文件,其核心實作如下:

const send = require(&#39;koa-send&#39;);
//...
function serve (root, opts) {
	//...
	return async function serve (ctx, next) {
		await next()
		if (ctx.method !== &#39;HEAD&#39; && ctx.method !== &#39;GET&#39;) 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(&#39;fs&#39;)
	const result=fs.readFileSync(&#39;xxx&#39;)
	ctx.type=type(result, encodingExt)
	ctx.body=result
})

Koa回顧

其實在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中文網其他相關文章!

陳述:
本文轉載於:csdn.net。如有侵權,請聯絡admin@php.cn刪除