68 lines
2.1 KiB
TypeScript
68 lines
2.1 KiB
TypeScript
// Favicon API - 返回系统设置的 logo 作为 favicon
|
||
import { NextRequest, NextResponse } from 'next/server'
|
||
import { prisma } from '@/lib/prisma'
|
||
import { rewriteStorageUrlForClient } from '@/lib/url-rewrite'
|
||
|
||
export const dynamic = 'force-dynamic'
|
||
export const runtime = 'nodejs'
|
||
|
||
export async function GET(request: NextRequest) {
|
||
try {
|
||
// 获取系统设置中的 headerLogoUrl
|
||
const settings = await prisma.systemSettings.findFirst({
|
||
select: {
|
||
headerLogoUrl: true,
|
||
}
|
||
})
|
||
|
||
const logoUrl = settings?.headerLogoUrl || 'https://s3.1080p.hk/shuzhou/2025/05/18/8ebadf0a7cc34eaea00e8619b8efb827.png'
|
||
|
||
// 根据用户网络位置重写 URL(内网用户使用内网地址)
|
||
const finalUrl = rewriteStorageUrlForClient(logoUrl, request) || logoUrl
|
||
|
||
// 获取 logo 图片
|
||
const response = await fetch(finalUrl, {
|
||
headers: {
|
||
'User-Agent': 'Mozilla/5.0 (compatible; FaviconFetcher/1.0)',
|
||
},
|
||
})
|
||
|
||
if (!response.ok) {
|
||
// 如果获取失败,返回默认的透明 PNG
|
||
const FAVICON_PNG = Buffer.from(
|
||
'iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAADUlEQVR42mNk+M9QDwADhgGAWjR9awAAAABJRU5ErkJggg==',
|
||
'base64'
|
||
)
|
||
return new NextResponse(FAVICON_PNG, {
|
||
headers: {
|
||
'Content-Type': 'image/png',
|
||
'Cache-Control': 'public, max-age=3600',
|
||
},
|
||
})
|
||
}
|
||
|
||
const arrayBuffer = await response.arrayBuffer()
|
||
const contentType = response.headers.get('content-type') || 'image/png'
|
||
|
||
return new NextResponse(arrayBuffer, {
|
||
headers: {
|
||
'Content-Type': contentType,
|
||
'Cache-Control': 'public, max-age=3600', // 缓存1小时
|
||
},
|
||
})
|
||
} catch (error) {
|
||
console.error('[Favicon API] Error:', error)
|
||
// 返回默认的透明 PNG
|
||
const FAVICON_PNG = Buffer.from(
|
||
'iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAADUlEQVR42mNk+M9QDwADhgGAWjR9awAAAABJRU5ErkJggg==',
|
||
'base64'
|
||
)
|
||
return new NextResponse(FAVICON_PNG, {
|
||
headers: {
|
||
'Content-Type': 'image/png',
|
||
'Cache-Control': 'public, max-age=3600',
|
||
},
|
||
})
|
||
}
|
||
}
|