This commit is contained in:
2026-05-08 20:48:29 +08:00
parent abf1f1ebea
commit 94975e4735
82 changed files with 7786 additions and 1012 deletions

View File

@@ -11,8 +11,9 @@ type AssetReadUrlResolveOptions = {
expireSeconds?: number;
/**
* 图片内容可能在同一路径下被重新写入。
* 这时需要显式跳过本地签名缓存,并在最终 URL 上追加一次性参数
* 避免结果页仍命中旧签名地址或浏览器图片缓存
* 对 generated 私有资源只跳过本地签名缓存并重新换签
* 不能给 OSS V4 签名 URL 追加一次性参数
* 普通非签名 URL 仍可追加 `_v` 避免浏览器图片缓存。
*/
refreshKey?: string | number | null;
};
@@ -45,7 +46,7 @@ const signedReadUrlFailureCache = new Map<string, CachedReadUrlFailureEntry>();
const pendingSignedReadUrlRequests = new Map<string, Promise<string>>();
export function isGeneratedLegacyPath(value: string) {
return /^\/generated-[^/?#]+\/.+/u.test(value.trim());
return /^\/?generated-[^/?#]+\/.+/u.test(value.trim());
}
function normalizeLegacyPublicPath(value: string) {
@@ -219,8 +220,17 @@ function appendCacheBustParam(
return url;
}
// OSS V4 签名会把 query 纳入签名计算,前端不能追加 `_v` 之类的缓存参数。
// 需要刷新时通过 refreshKey 绕过本地签名缓存,重新请求 `/api/assets/read-url`。
if (/[?&]x-oss-signature(?:=|&|$)/u.test(url)) {
return url;
}
try {
const parsedUrl = new URL(url, globalThis.location?.origin ?? 'http://localhost');
if (parsedUrl.searchParams.has('x-oss-signature')) {
return url;
}
parsedUrl.searchParams.set('_v', normalizedRefreshKey);
if (/^(?:https?:)?\/\//u.test(url)) {
return parsedUrl.toString();
@@ -262,7 +272,7 @@ export async function resolveAssetReadUrl(
options.refreshKey !== null && options.refreshKey !== undefined,
},
);
return appendCacheBustParam(signedUrl, options.refreshKey);
return signedUrl;
}
return appendCacheBustParam(value, options.refreshKey);