feat: URL 标题抓取改为通过后端代理
- 从直连 lpt-ai 的 /fetch-title 改为调用后端 /utils/fetch-title - 使用 Map 缓存 + pending 去重,避免重复请求 - 导出 getUrlTitle 单条获取函数,替代 fetchTitle/fetchTitles
This commit is contained in:
+19
-29
@@ -1,36 +1,26 @@
|
|||||||
/**
|
/**
|
||||||
* 网页标题抓取工具。
|
* URL 标题缓存 + 按需抓取,调用后端 /utils/fetch-title 代理
|
||||||
* 调用 lpt-ai 的 /fetch-title 接口获取 URL 对应的 <title> 标签内容。
|
|
||||||
*
|
|
||||||
* 设计要点:
|
|
||||||
* - 内存缓存避免同页面重复请求
|
|
||||||
* - 失败时回退到 URL 本身
|
|
||||||
* - 仅在 lpt-ai 运行时可用
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
const LPT_AI_URL = "http://localhost:5199";
|
import request from "@/utils/request";
|
||||||
|
|
||||||
const titleCache: Record<string, string> = {};
|
const cache = new Map<string, string>();
|
||||||
|
const pending = new Map<string, Promise<string>>();
|
||||||
|
|
||||||
export async function fetchTitle(url: string): Promise<string> {
|
export async function getUrlTitle(url: string): Promise<string> {
|
||||||
if (titleCache[url]) return titleCache[url];
|
if (cache.has(url)) return cache.get(url)!;
|
||||||
try {
|
if (pending.has(url)) return pending.get(url)!;
|
||||||
const res = await fetch(`${LPT_AI_URL}/fetch-title`, {
|
|
||||||
method: "POST",
|
|
||||||
headers: { "Content-Type": "application/json" },
|
|
||||||
body: JSON.stringify({ url }),
|
|
||||||
signal: AbortSignal.timeout(12_000),
|
|
||||||
});
|
|
||||||
if (!res.ok) return url;
|
|
||||||
const data = await res.json();
|
|
||||||
titleCache[url] = data.title || url;
|
|
||||||
return titleCache[url];
|
|
||||||
} catch {
|
|
||||||
return url;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/** 批量获取标题 */
|
const promise = request
|
||||||
export async function fetchTitles(urls: string[]): Promise<string[]> {
|
.get("/utils/fetch-title", { url })
|
||||||
return Promise.all(urls.map((url) => fetchTitle(url)));
|
.then((res: any) => {
|
||||||
|
const title = res?.data?.title || url;
|
||||||
|
cache.set(url, title);
|
||||||
|
return title;
|
||||||
|
})
|
||||||
|
.catch(() => url)
|
||||||
|
.finally(() => pending.delete(url));
|
||||||
|
|
||||||
|
pending.set(url, promise);
|
||||||
|
return promise;
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user