import { createReadStream, statSync } from 'node:fs' import { resolve, sep } from 'node:path' const contentTypes: Record = { jpg: 'image/jpeg', jpeg: 'image/jpeg', png: 'image/png', webp: 'image/webp', } export default defineEventHandler((event) => { const requested = getRouterParam(event, 'path') || '' const uploadsRoot = resolve(process.cwd(), 'data', 'uploads') const legacyRoot = resolve(process.cwd(), 'data', 'media') let mediaRoot = uploadsRoot let filePath = resolve(mediaRoot, requested) if (!filePath.startsWith(`${mediaRoot}${sep}`)) { throw createError({ statusCode: 400, statusMessage: '无效的文件路径' }) } let fileStat try { fileStat = statSync(filePath) } catch { const legacyPath = resolve(legacyRoot, requested) if (!legacyPath.startsWith(`${legacyRoot}${sep}`)) throw createError({ statusCode: 400, statusMessage: '无效的文件路径' }) try { fileStat = statSync(legacyPath); filePath = legacyPath; mediaRoot = legacyRoot } catch { throw createError({ statusCode: 404, statusMessage: '图片不存在' }) } } if (!fileStat.isFile()) { throw createError({ statusCode: 404, statusMessage: '图片不存在' }) } const extension = filePath.split('.').pop()?.toLowerCase() || '' const contentType = contentTypes[extension] if (!contentType) { throw createError({ statusCode: 415, statusMessage: '不支持的文件类型' }) } setHeader(event, 'Content-Type', contentType) setHeader(event, 'Content-Length', fileStat.size) setHeader(event, 'Cache-Control', 'public, max-age=31536000, immutable') return sendStream(event, createReadStream(filePath)) })