|
 关键是别直接把 <img> 指到一个可能不存在的地址。浏览器对 <img> 的 404 会直接在控制台打红字;
但如果你先用 fetch() 探测,404 只是一个“正常的失败”,不会红。
探测到存在后再把 img.src 设过去,就不会有 404 噪音了。
- async function pickExisting(urls) {
- // 并发探测:谁先返回 OK 就用谁
- const ctrls = [];
- const probes = urls.map(url => new Promise(async (resolve, reject) => {
- const ctrl = new AbortController();
- ctrls.push(ctrl);
- try {
- // 先 HEAD,部分静态服务器不支持 HEAD 就会 405
- let res = await fetch(url, { method: 'HEAD', cache: 'no-store', signal: ctrl.signal });
- if (!res.ok && (res.status === 405 || res.status === 501)) {
- // 回退到 GET(仍然不会在控制台打红字)
- res = await fetch(url, { method: 'GET', cache: 'no-store', signal: ctrl.signal });
- }
- if (res.ok) {
- // 找到后,取消其他请求
- ctrls.forEach(c => { if (c !== ctrl) c.abort(); });
- resolve(url);
- } else {
- reject(new Error(`${url} -> ${res.status}`));
- }
- } catch (e) {
- reject(e);
- }
- }));
- // 谁先成功用谁;都失败就抛
- return Promise.any(probes);
- }
- async function setCoverImage(imgEl, baseDir) {
- const candidates = [
- `${baseDir}/cover.jpg`,
- `${baseDir}/cover.jpeg`,
- `${baseDir}/cover.png`,
- `${baseDir}/cover.webp`
- ];
- try {
- const okUrl = await pickExisting(candidates);
- imgEl.src = okUrl; // 只在确认存在后再赋值,不会触发 404 日志
- } catch {
- imgEl.src = '/images/placeholder.svg'; // 可选:兜底图
- }
- }
- // 用法
- const img = document.querySelector('#album-cover');
- setCoverImage(img, '/music/abc'); // 这里的 baseDir 改成你的根目录
复制代码 |
|