You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

53 lines
1.3 KiB

/**
* 静态资源中间件 - 简化版本
*/
import fs from 'fs'
import NPath from 'path'
import { promisify } from 'util'
const stat = promisify(fs.stat)
export default function staticMiddleware(ctx, path, options = {}) {
const {
root,
maxAge = 0,
immutable = false
} = options
return new Promise(async (resolve, reject) => {
try {
const fullPath = NPath.resolve(root, path.startsWith('/') ? path.slice(1) : path)
// 检查文件是否存在
const stats = await stat(fullPath)
if (!stats.isFile()) {
return resolve() // reject(new Error('Not a file'))
}
// 设置响应头
ctx.set('Content-Length', stats.size)
ctx.set('Last-Modified', stats.mtime.toUTCString())
const directives = [`max-age=${Math.floor(maxAge / 1000)}`]
if (immutable) directives.push('immutable')
ctx.set('Cache-Control', directives.join(','))
// 设置内容类型
const ext = NPath.extname(fullPath)
if (ext) {
ctx.type = ext
}
// 发送文件
ctx.body = fs.createReadStream(fullPath)
resolve(fullPath)
} catch (err) {
if (err.code === 'ENOENT') {
err.status = 404
}
reject(err)
}
})
}