71 lines
2.4 KiB
JavaScript
71 lines
2.4 KiB
JavaScript
import fs from 'fs';
|
||
import path from 'path';
|
||
import { NextResponse } from 'next/server';
|
||
|
||
const BACKEND_SERVER_URL = process.env.BACKEND_SERVER_URL || '';
|
||
const PUBLIC_FILES_DIR = path.join(process.cwd(), 'public/files');
|
||
|
||
function getContentType(filePath) {
|
||
const ext = path.extname(filePath).toLowerCase();
|
||
switch (ext) {
|
||
case '.jpg':
|
||
case '.jpeg':
|
||
return 'image/jpeg';
|
||
case '.png':
|
||
return 'image/png';
|
||
case '.gif':
|
||
return 'image/gif';
|
||
case '.svg':
|
||
return 'image/svg+xml';
|
||
case '.webp':
|
||
return 'image/webp';
|
||
case '.mp4':
|
||
return 'video/mp4';
|
||
case '.pdf':
|
||
return 'application/pdf';
|
||
default:
|
||
return 'application/octet-stream';
|
||
}
|
||
}
|
||
|
||
export async function GET(req, { params }) {
|
||
try {
|
||
const parts = params.path || [];
|
||
const fileName = parts.join('/');
|
||
if (!fileName) return new NextResponse('Not Found', { status: 404 });
|
||
|
||
const localPath = path.join(PUBLIC_FILES_DIR, fileName);
|
||
|
||
if (fs.existsSync(localPath)) {
|
||
const data = fs.readFileSync(localPath);
|
||
return new NextResponse(data, {
|
||
status: 200,
|
||
headers: { 'Content-Type': getContentType(localPath), 'Cache-Control': 'public, max-age=31536000, immutable' }
|
||
});
|
||
}
|
||
|
||
const remoteUrl = `${BACKEND_SERVER_URL}/files/${fileName}`;
|
||
const res = await fetch(remoteUrl);
|
||
if (!res.ok) {
|
||
// 占位图(SVG),避免前端空白
|
||
const placeholder = `<svg xmlns="http://www.w3.org/2000/svg" width="800" height="450" viewBox="0 0 800 450"><rect width="800" height="450" fill="#f3f4f6"/><text x="50%" y="50%" dominant-baseline="middle" text-anchor="middle" fill="#9ca3af" font-size="20" font-family="Arial, Helvetica, sans-serif">Image unavailable</text></svg>`;
|
||
return new NextResponse(placeholder, { status: 200, headers: { 'Content-Type': 'image/svg+xml', 'Cache-Control': 'no-store' } });
|
||
}
|
||
const arrayBuffer = await res.arrayBuffer();
|
||
const buffer = Buffer.from(arrayBuffer);
|
||
|
||
// 确保目录存在并写入本地
|
||
fs.mkdirSync(path.dirname(localPath), { recursive: true });
|
||
fs.writeFileSync(localPath, buffer);
|
||
|
||
return new NextResponse(buffer, {
|
||
status: 200,
|
||
headers: { 'Content-Type': getContentType(localPath), 'Cache-Control': 'public, max-age=31536000, immutable' }
|
||
});
|
||
} catch (e) {
|
||
return new NextResponse('Server Error', { status: 500, headers: { 'Cache-Control': 'no-store' } });
|
||
}
|
||
}
|
||
|
||
|