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
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)
|
|
}
|
|
})
|
|
}
|