Descrizione del problema
Recentemente abbiamo riscontrato un problema con la visualizzazione delle immagini sul forum, in particolare:
- Le miniature delle immagini non vengono visualizzate correttamente.
- Facendo clic sulle immagini, viene visualizzata correttamente l’immagine a grandezza naturale.
- Gli strumenti per sviluppatori del browser mostrano URL delle immagini errati.
Dopo l’indagine, la causa principale è un nome di dominio errato negli URL delle immagini:
- URL corretto:
https://store.starorigin.cc/optimized/1X/[imageID].jpeg - URL errato:
https://info.7a4081a2d83d3f43fe6b1be1c926fd1c.r2.cloudflarestorage.com/optimized/1X/[imageID].jpeg
Il sistema sta utilizzando il dominio errato del bucket R2 grezzo invece del nostro dominio CDN configurato.
Analisi tecnica
Questo è un problema noto con Discourse quando gestisce immagini archiviate in Cloudflare R2. In alcuni casi, anche quando s3_cdn_url è configurato, Discourse potrebbe comunque utilizzare l’URL di archiviazione grezzo anziché l’URL CDN quando genera immagini ottimizzate (come le miniature).
Ciò potrebbe essere correlato ai seguenti fattori:
- Versione di Discourse
- La configurazione dello storage compatibile con S3
- Come gli URL sono archiviati nella tabella
OptimizedImage
Soluzione
La soluzione più semplice ed efficace è utilizzare un componente tema di Discourse per la riparazione lato client. Ciò non richiede operazioni sul database o modifiche alla configurazione del server. Coinvolge solo l’aggiunta di un breve snippet di codice JavaScript che sostituisce automaticamente gli URL errati con quelli corretti nel browser.
Codice del componente tema
import { apiInitializer } from "discourse/lib/api";
export default apiInitializer("0.11.1", (api) => {
// Correggi le immagini già caricate
function fixImageUrls() {
const badDomain = "info.7a4081a2d83d3f43fe6b1be1c926fd1c.r2.cloudflarestorage.com";
const goodDomain = "store.starorigin.cc";
// Correggi le immagini normali
document.querySelectorAll(`img[src*="${badDomain}"]`).forEach(img => {
img.src = img.src.replace(badDomain, goodDomain);
});
// Correggi le immagini lazy-loaded
document.querySelectorAll(`img[data-src*="${badDomain}"]`).forEach(img => {
img.setAttribute('data-src', img.getAttribute('data-src').replace(badDomain, goodDomain));
});
// Correggi le immagini di sfondo
document.querySelectorAll('[style*="background"]').forEach(el => {
if (el.style.backgroundImage && el.style.backgroundImage.includes(badDomain)) {
el.style.backgroundImage = el.style.backgroundImage.replace(badDomain, goodDomain);
}
});
// Correggi vari altri attributi potenziali
['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));
});
});
}
// Correggi le immagini nell'editor
api.decorateCooked($elem => {
fixImageUrls();
}, { id: 'fix-r2-image-urls' });
// Correggi dopo il caricamento iniziale
api.onPageChange(() => {
fixImageUrls();
});
// Gestisci contenuti caricati dinamicamente
const observer = new MutationObserver(mutations => {
fixImageUrls();
});
// Inizia l'osservazione dopo il caricamento del DOM
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']
});
}
});
Come funziona il codice
Questo codice esegue le seguenti azioni:
- Rilevamento completo: Trova tutti gli URL delle immagini contenenti il dominio errato.
- Gestione di elementi multipli: Gestisce vari elementi e attributi di immagine (tag img, immagini lazy-loaded, immagini di sfondo, ecc.).
- Monitoraggio dinamico: Utilizza un
MutationObserverper monitorare le modifiche della pagina, garantendo che anche i contenuti caricati dinamicamente vengano corretti. - Integrazione con Discourse: Si integra con l’API di Discourse per gestire vari scenari speciali.
Passaggi di installazione
- Accedi al tuo account amministratore di Discourse.
- Vai su Admin > Personalizza > Componenti tema.
- Fai clic sul pulsante Nuovo.
- Seleziona l’opzione Crea nuovo componente.
- Chiamalo “Fix R2 Image URLs” (o qualsiasi nome preferisci).
- Nella scheda “Javascript”, incolla il codice sopra.
- Fai clic sul pulsante Crea.
- Fai clic sul pulsante Abilita e scegli il tema a cui applicarlo (solitamente “Predefinito”).
Verifica
Dopo l’installazione:
- Aggiorna la pagina del forum.
- Visualizza i post contenenti immagini.
- Conferma che le miniature vengano visualizzate correttamente.
- Utilizza gli strumenti per sviluppatori del tuo browser per verificare che tutte le richieste di immagini puntino al dominio CDN.
Sebbene una soluzione lato client sia l’approccio più semplice, veloce e a minor rischio, specialmente quando l’accesso diretto al server è limitato.
Conclusione
Questo semplice componente tema risolve efficacemente il problema degli URL delle immagini durante l’integrazione di Discourse con lo storage Cloudflare R2, senza richiedere modifiche al server o configurazioni complesse. Sebbene risolva il problema lato client anziché affrontare la causa principale, è facile da implementare, fornisce risultati immediati ed è una soluzione ideale.
Se anche il tuo sito Discourse sta riscontrando problemi simili, sentiti libero di provare questa soluzione.
