Skip to content

Commit 4484f01

Browse files
authored
🐛 favicon 超时 (#540)
1 parent ed465e8 commit 4484f01

1 file changed

Lines changed: 26 additions & 15 deletions

File tree

src/pkg/utils/favicon.ts

Lines changed: 26 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -124,28 +124,35 @@ function parseFaviconsNew(html: string, callback: (href: string) => void) {
124124
return;
125125
}
126126

127+
// AbortSignal.timeout 是较新的功能。如果不支持 AbortSignal.timeout,则返回传统以定时器操作 AbortController
128+
const timeoutAbortSignal =
129+
typeof AbortSignal?.timeout === "function"
130+
? (milis: number) => {
131+
return AbortSignal.timeout(milis);
132+
}
133+
: (milis: number) => {
134+
let controller: AbortController | null = new AbortController();
135+
const signal = controller.signal;
136+
setTimeout(() => {
137+
controller!.abort(); // 中断请求
138+
controller = null;
139+
}, milis);
140+
return signal;
141+
};
142+
127143
/**
128144
* 从域名获取favicon
129145
*/
130146
async function getFaviconFromDomain(domain: string): Promise<string[]> {
131147
const url = `https://${domain}`;
132148
const icons: string[] = [];
133149

134-
// 创建 AbortController 实例
135-
const controller = new AbortController();
136-
const signal = controller.signal;
137-
138150
// 设置超时时间(例如 5 秒)
139151
const timeout = 5000; // 单位:毫秒
140152

141-
// 设置超时计时器
142-
const timeoutId = setTimeout(() => {
143-
controller.abort(); // 中断请求
144-
}, timeout);
145153
try {
146154
// 获取页面HTML
147-
148-
const response = await fetch(url, { signal });
155+
const response = await fetch(url, { signal: timeoutAbortSignal(timeout) });
149156
const html = await response.text();
150157

151158
parseFaviconsNew(html, (href) => icons.push(resolveUrl(href, url)));
@@ -154,7 +161,7 @@ async function getFaviconFromDomain(domain: string): Promise<string[]> {
154161
if (icons.length === 0) {
155162
const faviconUrl = `${url}/favicon.ico`;
156163
try {
157-
const faviconResponse = await fetch(faviconUrl, { method: "HEAD", signal });
164+
const faviconResponse = await fetch(faviconUrl, { method: "HEAD", signal: timeoutAbortSignal(timeout) });
158165
if (faviconResponse.ok) {
159166
icons.push(faviconUrl);
160167
}
@@ -164,11 +171,15 @@ async function getFaviconFromDomain(domain: string): Promise<string[]> {
164171
}
165172

166173
return icons;
167-
} catch (error) {
168-
console.error(`Error fetching favicon for ${domain}:`, error);
174+
} catch (error: any) {
175+
if (error.name === "AbortError") {
176+
// 超时
177+
console.warn(`Timeout while fetching favicon:`, url);
178+
} else {
179+
// 其他错误
180+
console.error(`Error fetching favicon for ${domain}:`, error);
181+
}
169182
return [];
170-
} finally {
171-
clearTimeout(timeoutId); // 清除超时计时器
172183
}
173184
}
174185

0 commit comments

Comments
 (0)