Descripción del problema
Recientemente hemos notado un problema con la visualización de imágenes en el foro, específicamente:
- Las miniaturas de las imágenes no se muestran correctamente.
- Al hacer clic en las imágenes, se muestra la imagen a tamaño completo correctamente.
- Las herramientas de desarrollador del navegador muestran URL de imágenes incorrectas.
Después de la investigación, la causa raíz es un nombre de dominio incorrecto en las URL de las imágenes:
- URL correcta:
https://store.starorigin.cc/optimized/1X/[imageID].jpeg - URL incorrecta:
https://info.7a4081a2d83d3f43fe6b1be1c926fd1c.r2.cloudflarestorage.com/optimized/1X/[imageID].jpeg
El sistema está utilizando el dominio incorrecto del bucket R2 en bruto en lugar de nuestro dominio CDN configurado.
Análisis técnico
Este es un problema conocido con Discourse al manejar imágenes almacenadas en Cloudflare R2. En algunos casos, incluso cuando s3_cdn_url está configurado, Discourse podría seguir utilizando la URL de almacenamiento en bruto en lugar de la URL CDN al generar imágenes optimizadas (como miniaturas).
Esto podría estar relacionado con los siguientes factores:
- Versión de Discourse
- La configuración del almacenamiento compatible con S3
- Cómo se almacenan las URL en la tabla
OptimizedImage
Solución
La solución más sencilla y eficaz es utilizar un componente temático de Discourse para la reparación del lado del cliente. Esto no requiere ninguna operación de base de datos ni cambios en la configuración del servidor. Solo implica agregar un pequeño fragmento de código JavaScript que reemplaza automáticamente las URL incorrectas por las correctas en el navegador.
Código del componente temático
import { apiInitializer } from "discourse/lib/api";
export default apiInitializer("0.11.1", (api) => {
// Corregir imágenes ya cargadas
function fixImageUrls() {
const badDomain = "info.7a4081a2d83d3f43fe6b1be1c926fd1c.r2.cloudflarestorage.com";
const goodDomain = "store.starorigin.cc";
// Corregir imágenes normales
document.querySelectorAll(`img[src*="${badDomain}"]`).forEach(img => {
img.src = img.src.replace(badDomain, goodDomain);
});
// Corregir imágenes de carga diferida
document.querySelectorAll(`img[data-src*="${badDomain}"]`).forEach(img => {
img.setAttribute('data-src', img.getAttribute('data-src').replace(badDomain, goodDomain));
});
// Corregir imágenes de fondo
document.querySelectorAll('[style*="background"]').forEach(el => {
if (el.style.backgroundImage && el.style.backgroundImage.includes(badDomain)) {
el.style.backgroundImage = el.style.backgroundImage.replace(badDomain, goodDomain);
}
});
// Corregir varios otros atributos potenciales
['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));
});
});
}
// Corregir imágenes en el editor
api.decorateCooked($elem => {
fixImageUrls();
}, { id: 'fix-r2-image-urls' });
// Corregir después de la carga inicial
api.onPageChange(() => {
fixImageUrls();
});
// Manejar contenido cargado dinámicamente
const observer = new MutationObserver(mutations => {
fixImageUrls();
});
// Comenzar a observar después de que el DOM esté cargado
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']
});
}
});
Cómo funciona el código
Este código realiza las siguientes acciones:
- Detección integral: Encuentra todas las URL de imágenes que contienen el dominio incorrecto.
- Manejo de múltiples elementos: Maneja varios elementos y atributos de imágenes (etiquetas img, imágenes de carga diferida, imágenes de fondo, etc.).
- Monitoreo dinámico: Utiliza un
MutationObserverpara monitorear los cambios en la página, asegurando que el contenido cargado dinámicamente también se corrija. - Integración con Discourse: Se integra con la API de Discourse para manejar varios escenarios especiales.
Pasos de instalación
- Inicie sesión en su cuenta de administrador de Discourse.
- Vaya a Admin > Personalizar > Componentes temáticos.
- Haga clic en el botón Nuevo.
- Seleccione la opción Crear nuevo componente.
- Nómbrelo “Corregir URL de imágenes R2” (o el nombre que prefiera).
- En la pestaña “Javascript”, pegue el código anterior.
- Haga clic en el botón Crear.
- Haga clic en el botón Habilitar y elija el tema al que aplicarlo (generalmente “Predeterminado”).
Verificación
Después de la instalación:
- Actualice la página del foro.
- Vea las publicaciones que contienen imágenes.
- Confirme que las miniaturas se muestran correctamente.
- Utilice las herramientas de desarrollador de su navegador para verificar que todas las solicitudes de imágenes apunten al dominio CDN.
Si bien una solución del lado del cliente es el enfoque más simple, rápido y de menor riesgo, especialmente cuando el acceso directo al servidor es limitado.
Conclusión
Este sencillo componente temático aborda eficazmente el problema de las URL de imágenes al integrar Discourse con el almacenamiento Cloudflare R2, sin necesidad de cambios en el servidor o configuraciones complejas. Aunque soluciona el problema en el lado del cliente en lugar de abordar la causa raíz, es fácil de implementar, proporciona resultados inmediatos y es una solución ideal.
Si su sitio de Discourse también está experimentando problemas similares, no dude en probar esta solución.
