/** * 静态资源中间件 - 简化版本 */ 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) } }) }