refactor: 将文件请求由app端转到server端
All checks were successful
deploy to server / build-and-deploy (push) Successful in 3m2s

This commit is contained in:
2025-11-12 18:19:21 +08:00
parent a5f3895794
commit a520775a8d
5 changed files with 49 additions and 28 deletions

View File

@ -122,6 +122,8 @@
const errorText = computed(() => error.value?.message ?? null);
const fileMeta = computed(() => props.file ?? data.value ?? null);
logger.debug('FilePreviewer - fileMeta:', fileMeta.value);
/** 预览源地址:支持在 file.url 上追加额外 query如临时 token、inline */
const src = computed<string>(() => {
if (!fileMeta.value) return '';

View File

@ -1,19 +1,14 @@
export const useDirectusFiles = () => {
const config = useRuntimeConfig();
const baseUrl = config.public.directus.url;
const getFileUrl = (
id?: string | null,
options?: Record<string, string | number | boolean>
): string => {
if (!id) return '';
const query = options
? '?' +
new URLSearchParams(
Object.entries(options).map(([key, value]) => [key, String(value)])
).toString()
: '';
return `${baseUrl}/assets/${id}${query}`;
const params = new URLSearchParams(
options as Record<string, string>
).toString();
return `/api/assets/${id}${params ? `?${params}` : ''}`;
};
return {

View File

@ -1,8 +1,4 @@
export const useDirectusImage = () => {
const config = useRuntimeConfig();
const baseUrl = config.public.directus.url;
const token = config.public.directus.token;
type DirectusAssetParams = {
width?: number;
height?: number;
@ -13,19 +9,11 @@ export const useDirectusImage = () => {
const getImageUrl = (id?: string | null, options?: DirectusAssetParams) => {
if (!id) return '';
const queryToken = token ? 'access_token=' + token : '';
const queryOptions = options
? new URLSearchParams(
Object.fromEntries(
Object.entries(options).map(([key, value]) => [key, String(value)])
)
).toString
: '';
const query =
queryToken || queryOptions
? `?${[queryToken, queryOptions].filter(Boolean).join('&')}`
: '';
return `${baseUrl}/assets/${id}${query}`;
const params = new URLSearchParams(
options as Record<string, string>
).toString();
return `/api/assets/${id}${params ? `?${params}` : ''}`;
};
return { getImageUrl };

36
server/api/assets/[id].ts Normal file
View File

@ -0,0 +1,36 @@
export default defineEventHandler(async (event) => {
const id = getRouterParam(event, 'id');
if (!id)
throw createError({
statusCode: 400,
statusMessage: 'ID parameter is required',
});
const url = new URL(`${useRuntimeConfig().public.directus.url}/assets/${id}`);
const query = getQuery(event);
Object.entries(query).forEach(([key, value]) => {
url.searchParams.set(key, String(value));
});
const token = useRuntimeConfig().public.directus.token || '';
const res = await fetch(url.toString(), {
headers: {
Authorization: `Bearer ${token}`,
},
});
if (!res.ok) {
throw createError({
statusCode: res.status,
statusMessage: `Failed to fetch asset: ${res.statusText}`,
});
}
const contentType =
res.headers.get('Content-Type') || 'application/octet-stream';
setHeader(event, 'Content-Type', contentType);
setHeader(event, 'Cache-Control', 'public, max-age=86400, immutable');
return res.body;
});

View File

@ -41,7 +41,7 @@ export async function getFileMeta(id: string): Promise<FileMeta | null> {
width: file.width ?? undefined,
height: file.height ?? undefined,
uploaded_on: file.uploaded_on ?? undefined,
url: `${baseUrl}/assets/${file.id}`,
url: `/api/assets/${file.id}`,
previewable: isPreviewable(file.type),
};
} catch (error) {