ZZY 73917d6001 dev feat(markcard, static): 实现书签卡片功能和静态资源获取
- 书签卡片相关的组件和页面
- 实现书签数据的获取、添加、编辑和删除功能
- 添加用户验证和权限控制
- 优化页面布局和样式
2024-12-22 15:21:07 +08:00

70 lines
2.0 KiB
TypeScript

import { NextRequest, NextResponse } from 'next/server'
import fs from 'fs/promises'
import path from 'path'
import env from '@/lib/env';
import resolveFilePath from '@/lib/file';
// 白名单:允许访问的文件扩展名
const allowedExtensions = ['.html', '.js', '.css', '.json', '.png', '.jpg', '.jpeg', '.gif', '.svg'];
const basePath = path.join(process.cwd(), env('STATIC_FILE_PATH'))
export async function GET(req: NextRequest,
{ params }: { params: Promise<{ path?: string[] }> }
) {
const fileseg = (await params).path
const filepath = resolveFilePath(fileseg, basePath, allowedExtensions, ['index.html'])
if (filepath === null) {
return NextResponse.json({ message: 'File not found' }, { status: 404 })
}
try {
// 获取文件扩展名以确定 MIME 类型
const extname = path.extname(filepath).toLowerCase();
if (!allowedExtensions.includes(extname)) {
return NextResponse.json({ error: 'Forbidden file type' }, { status: 403 });
}
// 设置响应头
let contentType = 'text/plain';
switch (extname) {
case '.html':
contentType = 'text/html';
break;
case '.js':
contentType = 'text/javascript';
break;
case '.css':
contentType = 'text/css';
break;
case '.json':
contentType = 'application/json';
break;
case '.png':
contentType = 'image/png';
break;
case '.jpg':
case '.jpeg':
contentType = 'image/jpeg';
break;
case '.gif':
contentType = 'image/gif';
break;
case '.svg':
contentType = 'image/svg+xml';
break;
default:
contentType = 'text/plain';
}
const responseHeaders = new Headers();
responseHeaders.set('Content-Type', contentType);
// 返回文件内容
return new NextResponse(await fs.readFile(filepath), { status: 200, headers: responseHeaders });
} catch (err) {
console.error(err);
return NextResponse.json({ error: 'Internal Server Error' }, { status: 500 });
}
}