Files
Genarrative/src/hooks/useResolvedAssetReadUrl.ts
kdletters 2a6da01307 修复生成图片签名地址重复换签
将 refreshKey 调整为 signed URL 缓存版本号,同一路径同版本复用未过期签名地址。

让完整阿里云 OSS generated 地址在 hook 中先归一并走 read-url 换签。

补充前端回归测试,覆盖相同 refreshKey 不重复换签和完整 OSS 地址不裸写入图片。

更新运维文档与 Hermes 记忆,明确 refreshKey 不是每次绕过签名缓存。
2026-06-07 23:20:24 +08:00

73 lines
1.7 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
import { useEffect, useState } from 'react';
import {
resolveAssetReadUrl,
shouldResolveAssetReadUrl,
} from '../services/assetReadUrlService';
type UseResolvedAssetReadUrlOptions = {
enabled?: boolean;
expireSeconds?: number;
refreshKey?: string | number | null;
};
export function useResolvedAssetReadUrl(
source: string | null | undefined,
options: UseResolvedAssetReadUrlOptions = {},
) {
const enabled = options.enabled !== false;
const normalizedSource = source?.trim() ?? '';
const shouldResolve =
enabled && shouldResolveAssetReadUrl(normalizedSource);
const [resolvedUrl, setResolvedUrl] = useState(
shouldResolve ? '' : normalizedSource,
);
useEffect(() => {
if (!normalizedSource) {
setResolvedUrl('');
return;
}
if (!shouldResolve) {
setResolvedUrl(normalizedSource);
return;
}
let cancelled = false;
// 生成资源通常是 OSS 私有对象;签名 URL 未就绪前不能把裸 generated 路径交给 img 触发无鉴权 GET。
setResolvedUrl('');
void resolveAssetReadUrl(normalizedSource, {
expireSeconds: options.expireSeconds,
refreshKey: options.refreshKey,
})
.then((nextUrl) => {
if (!cancelled) {
setResolvedUrl(nextUrl);
}
})
.catch(() => {
if (!cancelled) {
// 签名失败时保持空 src避免继续请求无签名的私有对象兼容路径。
setResolvedUrl('');
}
});
return () => {
cancelled = true;
};
}, [
normalizedSource,
options.expireSeconds,
options.refreshKey,
shouldResolve,
]);
return {
resolvedUrl,
isResolving: shouldResolve && !resolvedUrl,
shouldResolve,
};
}