Problembeschreibung
Wir haben kürzlich ein Problem mit der Bildanzeige im Forum festgestellt, insbesondere:
- Bild-Thumbnails werden nicht korrekt angezeigt.
- Beim Klicken auf die Bilder wird das Vollbildbild korrekt angezeigt.
- Die Entwicklertools des Browsers zeigen falsche Bild-URLs an.
Nach der Untersuchung ist die Ursache ein falscher Domainname in den Bild-URLs:
- Korrekte URL:
https://store.starorigin.cc/optimized/1X/[imageID].jpeg - Falsche URL:
https://info.7a4081a2d83d3f43fe6b1be1c926fd1c.r2.cloudflarestorage.com/optimized/1X/[imageID].jpeg
Das System verwendet die falsche Domain des R2-Buckets anstelle unserer konfigurierten CDN-Domain.
Technische Analyse
Dies ist ein bekanntes Problem mit Discourse bei der Verarbeitung von Bildern, die in Cloudflare R2 gespeichert sind. In einigen Fällen kann Discourse, selbst wenn s3_cdn_url konfiguriert ist, beim Generieren optimierter Bilder (wie Thumbnails) immer noch die rohe Speicher-URL anstelle der CDN-URL verwenden.
Dies könnte mit folgenden Faktoren zusammenhängen:
- Discourse-Version
- Die Konfiguration des S3-kompatiblen Speichers
- Wie URLs in der
OptimizedImage-Tabelle gespeichert werden
Lösung
Die einfachste und effektivste Lösung ist die Verwendung einer Discourse-Themenkomponente zur clientseitigen Reparatur. Dies erfordert keine Datenbankoperationen oder Änderungen an der Serverkonfiguration. Es beinhaltet lediglich das Hinzufügen eines kurzen JavaScript-Code-Snippets, das die falschen URLs im Browser automatisch durch die richtigen ersetzt.
Code der Themenkomponente
import { apiInitializer } from "discourse/lib/api";
export default apiInitializer("0.11.1", (api) => {
// Bereits geladene Bilder reparieren
function fixImageUrls() {
const badDomain = "info.7a4081a2d83d3f43fe6b1be1c926fd1c.r2.cloudflarestorage.com";
const goodDomain = "store.starorigin.cc";
// Normale Bilder reparieren
document.querySelectorAll(`img[src*="${badDomain}"]`).forEach(img => {
img.src = img.src.replace(badDomain, goodDomain);
});
// Lazy-loaded Bilder reparieren
document.querySelectorAll(`img[data-src*="${badDomain}"]`).forEach(img => {
img.setAttribute('data-src', img.getAttribute('data-src').replace(badDomain, goodDomain));
});
// Hintergrundbilder reparieren
document.querySelectorAll('[style*="background"]').forEach(el => {
if (el.style.backgroundImage && el.style.backgroundImage.includes(badDomain)) {
el.style.backgroundImage = el.style.backgroundImage.replace(badDomain, goodDomain);
}
});
// Verschiedene andere potenzielle Attribute reparieren
['srcset', 'data-large-src', 'data-small-src', 'data-download-href'].forEach(attr => {
document.querySelectorAll(`[${attr}*="${badDomain}"]`).forEach(el => {
el.setAttribute(attr, el.getAttribute(attr).replace(badDomain, goodDomain));
});
});
}
// Bilder im Editor reparieren
api.decorateCooked($elem => {
fixImageUrls();
}, { id: 'fix-r2-image-urls' });
// Nach dem initialen Laden reparieren
api.onPageChange(() => {
fixImageUrls();
});
// Dynamisch geladene Inhalte behandeln
const observer = new MutationObserver(mutations => {
fixImageUrls();
});
// Beobachtung starten, nachdem das DOM geladen ist
if (document.readyState === "loading") {
document.addEventListener('DOMContentLoaded', () => {
fixImageUrls();
startObserver();
});
} else {
fixImageUrls();
startObserver();
}
function startObserver() {
observer.observe(document.body, {
childList: true,
subtree: true,
attributes: true,
attributeFilter: ['src', 'data-src', 'srcset', 'style']
});
}
});
Funktionsweise des Codes
Dieser Code führt folgende Aktionen aus:
- Umfassende Erkennung: Findet alle Bild-URLs, die die falsche Domain enthalten.
- Behandlung mehrerer Elemente: Behandelt verschiedene Bildelemente und Attribute (img-Tags, lazy-loaded Bilder, Hintergrundbilder usw.).
- Dynamische Überwachung: Verwendet einen
MutationObserver, um Seitenänderungen zu überwachen und sicherzustellen, dass auch dynamisch geladene Inhalte repariert werden. - Discourse-Integration: Integriert sich in die Discourse-API, um verschiedene Sonderszenarien zu behandeln.
Installationsschritte
- Melden Sie sich bei Ihrem Discourse-Administratorkonto an.
- Gehen Sie zu Admin > Anpassen > Themenkomponenten.
- Klicken Sie auf die Schaltfläche Neu.
- Wählen Sie die Option Neue Komponente erstellen.
- Benennen Sie sie „Fix R2 Image URLs“ (oder einen beliebigen Namen Ihrer Wahl).
- Fügen Sie im Tab „Javascript“ den obigen Code ein.
- Klicken Sie auf die Schaltfläche Erstellen.
- Klicken Sie auf die Schaltfläche Aktivieren und wählen Sie das Thema aus, auf das Sie sie anwenden möchten (normalerweise „Standard“).
Überprüfung
Nach der Installation:
- Aktualisieren Sie die Forumseite.
- Zeigen Sie Beiträge mit Bildern an.
- Bestätigen Sie, dass die Thumbnails korrekt angezeigt werden.
- Verwenden Sie die Entwicklertools Ihres Browsers, um zu überprüfen, ob alle Bildanfragen auf die CDN-Domain verweisen.
Obwohl eine clientseitige Lösung der einfachste, schnellste und risikoärmste Ansatz ist, insbesondere wenn der direkte Serverzugriff begrenzt ist.
Fazit
Diese einfache Themenkomponente behebt effektiv das Problem mit den Bild-URLs bei der Integration von Discourse mit Cloudflare R2-Speicher, ohne dass Serveränderungen oder komplexe Konfigurationen erforderlich sind. Obwohl sie das Problem clientseitig behebt und nicht die eigentliche Ursache angeht, ist sie einfach zu implementieren, liefert sofortige Ergebnisse und ist eine ideale Lösung.
Wenn Ihre Discourse-Site ebenfalls ähnliche Probleme hat, können Sie diese Lösung gerne ausprobieren.
