كل من عرض يوماً قائمة صور قادمة من بيانات لا يثق بها يعرف القصة جيداً. معظم الروابط تعمل، وواحد أو اثنان معطّلان، وأيقونة الصورة المكسورة تكفي وحدها لتخريب التصميم كاملاً. أمامك خياران: تلفّ كل شيء داخل try/catch، أو تسأل المتصفح مباشرةً وتدعه يجيب بنفسه: هل يمكنك تحميل هذا الرابط؟
هذا تحديداً ما كتبتُ checkUrl من أجله. تُعيد لك Promise ينجح تحليلها عند تحميل الصورة، ويُرفض عند فشلها. بلا fetch، وبلا صداع CORS، وبلا حاجة لإطلاق طلبات HEAD يدوياً.
الفكرة
Promise ينجح تحليلها أو تُرفض بحسب ما إذا كانت الصورة قد تحمّلت:
// success
const promise = new Promise<void>((resolve, reject) => { resolve() })
// failure
const promise = new Promise<void>((resolve, reject) => { reject() })
الاستعانة بكائن Image الجاهز في المتصفح
داخل الـ callback، أنشئ Image، اربط onload وonerror، ثم اضبط src ليبدأ الطلب.
const img = new Image();
img.onload = () => resolve();
img.onerror = () => reject();
img.src = url;
هذه هي الحكاية كلها. المتصفح يتكفّل بالعمل الفعلي، وPromise مجرد غلاف رفيع حول حدثين لا أكثر.
استخدامها مع صورة احتياطية
الحالة الأكثر شيوعاً عندي هي التبديل إلى صورة احتياطية حين يكون الرابط الأصلي معطّلاً.
const fallbackImage = 'https://example.com/fallback.png';
let url: string = anonymousOBJECT.image;
const checkImage = async () => {
try {
await checkUrl(url);
// valid, keep the original
} catch {
// invalid, swap in the fallback
url = fallbackImage;
}
};
checkImage();
<img :src="url" />
لا معالجة أخطاء داخل القالب، ولا وميض مزعج لصورة مكسورة، والرابط يصل جاهزاً إلى الـ DOM.
نُشر أصلاً على LinkedIn.

