وصف المشكلة
لقد لاحظنا مؤخرًا مشكلة في عرض الصور في المنتدى، وتحديدًا:
- الصور المصغرة لا يتم عرضها بشكل صحيح.
- النقر على الصور يعرض الصورة بالحجم الكامل بشكل صحيح.
- أدوات المطور في المتصفح تظهر عناوين URL غير صحيحة للصور.
بعد التحقيق، السبب الجذري هو اسم نطاق غير صحيح في عناوين URL للصور:
- عنوان URL الصحيح:
https://store.starorigin.cc/optimized/1X/[imageID].jpeg - عنوان URL غير الصحيح:
https://info.7a4081a2d83d3f43fe6b1be1c926fd1c.r2.cloudflarestorage.com/optimized/1X/[imageID].jpeg
يستخدم النظام اسم النطاق الخاطئ لمخزن R2 الخام بدلاً من اسم نطاق شبكة توصيل المحتوى (CDN) المكون لدينا.
التحليل الفني
هذه مشكلة معروفة في Discourse عند التعامل مع الصور المخزنة في Cloudflare R2. في بعض الحالات، حتى عند تكوين s3_cdn_url، قد لا يزال Discourse يستخدم عنوان URL للتخزين الخام بدلاً من عنوان URL لشبكة توصيل المحتوى عند إنشاء صور محسّنة (مثل الصور المصغرة).
قد يرتبط هذا بالعوامل التالية:
- إصدار Discourse
- تكوين التخزين المتوافق مع S3
- كيفية تخزين عناوين URL في جدول
OptimizedImage
الحل
الحل الأبسط والأكثر فعالية هو استخدام مكون سمة Discourse للإصلاح من جانب العميل. هذا لا يتطلب أي عمليات قاعدة بيانات أو تغييرات في تكوين الخادم. يتضمن فقط إضافة مقتطف رمز JavaScript صغير يقوم تلقائيًا باستبدال عناوين URL غير الصحيحة بالعناوين الصحيحة في المتصفح.
كود مكون السمة
import { apiInitializer } from "discourse/lib/api";
export default apiInitializer("0.11.1", (api) => {
// إصلاح الصور التي تم تحميلها بالفعل
function fixImageUrls() {
const badDomain = "info.7a4081a2d83d3f43fe6b1be1c926fd1c.r2.cloudflarestorage.com";
const goodDomain = "store.starorigin.cc";
// إصلاح الصور العادية
document.querySelectorAll(`img[src*="${badDomain}"]`).forEach(img => {
img.src = img.src.replace(badDomain, goodDomain);
});
// إصلاح الصور المحملة بكسل
document.querySelectorAll(`img[data-src*="${badDomain}"]`).forEach(img => {
img.setAttribute('data-src', img.getAttribute('data-src').replace(badDomain, goodDomain));
});
// إصلاح الصور الخلفية
document.querySelectorAll('[style*="background"]').forEach(el => {
if (el.style.backgroundImage && el.style.backgroundImage.includes(badDomain)) {
el.style.backgroundImage = el.style.backgroundImage.replace(badDomain, goodDomain);
}
});
// إصلاح سمات أخرى محتملة مختلفة
['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));
});
});
}
// إصلاح الصور في المحرر
api.decorateCooked($elem => {
fixImageUrls();
}, { id: 'fix-r2-image-urls' });
// الإصلاح بعد التحميل الأولي
api.onPageChange(() => {
fixImageUrls();
});
// التعامل مع المحتوى المحمل ديناميكيًا
const observer = new MutationObserver(mutations => {
fixImageUrls();
});
// بدء المراقبة بعد تحميل 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']
});
}
});
كيفية عمل الكود
يقوم هذا الكود بتنفيذ الإجراءات التالية:
- الكشف الشامل: يحدد جميع عناوين URL للصور التي تحتوي على النطاق غير الصحيح.
- التعامل مع عناصر متعددة: يتعامل مع عناصر وسمات الصور المختلفة (علامات img، الصور المحملة بكسل، الصور الخلفية، إلخ).
- المراقبة الديناميكية: يستخدم
MutationObserverلمراقبة تغييرات الصفحة، مما يضمن إصلاح المحتوى المحمل ديناميكيًا أيضًا. - التكامل مع Discourse: يتكامل مع واجهة برمجة تطبيقات Discourse للتعامل مع سيناريوهات خاصة مختلفة.
خطوات التثبيت
- قم بتسجيل الدخول إلى حساب مسؤول Discourse الخاص بك.
- انتقل إلى Admin > Customize > Theme Components.
- انقر فوق الزر New.
- حدد خيار Create new component.
- قم بتسميته “Fix R2 Image URLs” (أو أي اسم تفضله).
- في علامة التبويب “Javascript”، الصق الكود أعلاه.
- انقر فوق الزر Create.
- انقر فوق الزر Enable واختر السمة لتطبيقها عليها (عادةً “Default”).
التحقق
بعد التثبيت:
- قم بتحديث صفحة المنتدى.
- اعرض المشاركات التي تحتوي على صور.
- تأكد من عرض الصور المصغرة بشكل صحيح.
- استخدم أدوات المطور في متصفحك للتحقق من أن جميع طلبات الصور تشير إلى نطاق شبكة توصيل المحتوى (CDN).
في حين أن الحل من جانب العميل هو النهج الأبسط والأسرع والأقل خطورة، خاصة عندما يكون الوصول المباشر إلى الخادم محدودًا.
الخلاصة
يقوم مكون السمة البسيط هذا بمعالجة مشكلة عنوان URL للصور بشكل فعال عند دمج Discourse مع تخزين Cloudflare R2، دون الحاجة إلى تغييرات في الخادم أو تكوينات معقدة. على الرغم من أنه يصلح المشكلة من جانب العميل بدلاً من معالجة السبب الجذري، إلا أنه سهل التنفيذ، ويوفر نتائج فورية، وهو حل مثالي.
إذا كان موقع Discourse الخاص بك يواجه مشاكل مماثلة، فلا تتردد في تجربة هذا الحل.
