Resurs yuklash: onload va onerror
Brauzer bizga tashqi resurslar โ skriptlar, rasm, iframe va boshqalar โ yuklanishini kuzatish imkonini beradi. Buning uchun ikkita asosiy hodisa bor: load โ resurs muvaffaqiyatli yuklandi va error โ yuklashda xatolik yuz berdi. Bu, masalan, skriptni dinamik yuklab, u tayyor bo'lgach undagi funksiyalarni chaqirish uchun, yoki rasm yuklanmaganda zaxira rasmni ko'rsatish uchun kerak bo'ladi. Ushbu darsda resurs yuklanishini kuzatishni chuqur o'rganamiz.
document) tegishli. Kurs maydonchasi Node.js muhitida ishlaydi va DOM'ga ega emas โ shu sabab misollar statik, faqat o'qish uchun keltiriladi.load va error hodisalari
Ko'pchilik resurslar, ya'ni tashqi srcga ega elementlar (rasm, tashqi skript va h.k.) ikkita hodisani generatsiya qiladi:
loadโ resurs muvaffaqiyatli yuklanganda;errorโ resursni yuklashda xatolik yuz berganda.
Istisno: <iframe> โ u tarixiy sabablarga ko'ra yuklash tugagach har doim loadni generatsiya qiladi, hatto sahifa topilmasa ham.
Skriptni yuklashni kuzatish (script.onload)
Aytaylik, biz tashqi skriptdagi funksiyani chaqirmoqchimiz. Skriptni dinamik yuklaymiz:
let script = document.createElement('script');
script.src = 'https://cdn.jsdelivr.net/npm/lodash@4.17.21/lodash.min.js';
document.head.append(script);
Lekin skript yuklanguncha undagi funksiyalarni chaqira olmaymiz. Skript qachon tayyor bo'lishini bilish uchun load hodisasidan foydalanamiz:
let script = document.createElement('script');
script.src = 'https://cdn.jsdelivr.net/npm/lodash@4.17.21/lodash.min.js';
document.head.append(script);
script.onload = function() {
// skript yuklandi, endi undagi o'zgaruvchi va funksiyalar mavjud
alert(_.VERSION); // lodash kutubxonasi versiyasi
};
onload ishlovchisi skript yuklanib, bajarilib bo'lgach ishga tushadi. Shu paytda skript e'lon qilgan barcha o'zgaruvchi va funksiyalardan foydalanish mumkin.
script.onerror
Skriptni yuklashda xatoliklarni ham kuzatishimiz kerak. error hodisasi yuklash muvaffaqiyatsiz bo'lganda ishga tushadi:
let script = document.createElement('script');
script.src = 'https://example.com/mavjud-emas.js'; // bunday skript yo'q
document.head.append(script);
script.onerror = function() {
alert('Xatolik: ' + this.src + ' yuklanmadi');
};
Bu yerda mavjud bo'lmagan skript yuklanishga urinilgani uchun onerror ishga tushadi.
onload/onerror faqat yuklash jarayonining o'zini kuzatadi โ resurs olindimi yoki yo'qmi. Agar skript yuklandi, lekin uning ichida xatolik bo'lsa (masalan, kod ichida throw yoki sintaksis xatosi), buni onerror ushlamaydi. Yuklash muvaffaqiyatli bo'lgani uchun onload baribir ishga tushadi. Kod ichidagi xatoliklarni kuzatish uchun window.onerror global ishlovchisidan foydalaniladi.Boshqa resurslar (rasm, iframe)
load va error hodisalari boshqa resurslar uchun ham ishlaydi, ba'zi nozikliklar bilan.
Rasmlar (<img>), tashqi stillar, skriptlar va boshqa resurslarda onload va onerror hodisalari mavjud:
let img = document.createElement('img');
img.src = 'https://js.cx/clipart/train.gif'; // yuklashni boshlaydi
img.onload = function() {
alert(`Rasm yuklandi, o'lchami: ${img.width}x${img.height}`);
};
img.onerror = function() {
alert('Rasm yuklashda xatolik');
};
Rasm uchun ba'zi nozikliklar bor: aksariyat brauzerlarda rasmni yuklash src tayinlangan zahoti boshlanadi (elementni documentga qo'shish shart emas). Shu sabab onloadni srcdan oldin tayinlash yaxshi amaliyot โ aks holda keshdagi rasm darhol yuklanib, hodisani "o'tkazib yuborish" ehtimoli bor:
let img = document.createElement('img');
// avval hodisa ishlovchilarini tayinlaymiz
img.onload = () => alert('Yuklandi');
img.onerror = () => alert('Xatolik');
// keyin src โ shu paytda yuklash boshlanadi
img.src = 'https://js.cx/clipart/train.gif';
<iframe> uchun load hodisasi iframe ichidagi sahifa yuklanib bo'lgach ishlaydi โ muvaffaqiyatli ham, muvaffaqiyatsiz ham (masalan, 404). Bu tarixiy xususiyat, shuning uchun iframe'da error hodisasiga ishonib bo'lmaydi.Crossorigin siyosati (crossorigin atributi)
Bir muhim qoida bor: bir saytdagi (origin) skript boshqa saytning ichki ma'lumotlariga kira olmaydi. Aniqrog'i, bitta origin (domen/port/protokol) boshqasidagi resurs tarkibiga to'liq kira olmaydi. Bu "Same-Origin Policy" (bir manba siyosati) deb ataladi va xavfsizlik uchun mavjud.
Agar boshqa domendan (masalan, CDN'dan) yuklangan skriptda xatolik yuz bersa, window.onerror global ishlovchisi bu haqda batafsil ma'lumot ololmaydi โ u faqat qisqa "Script error" xabarini oladi, satr raqami yoki xato tafsilotlarisiz. Bu xavfsizlik cheklovi.
Buning sababi โ skript boshqa domendan bo'lsa, uning ichki xatolik ma'lumotini ko'rsatish maxfiy ma'lumotning sizib chiqishiga olib kelishi mumkin. Masalan, boshqa domendagi skript ichida foydalanuvchiga xos ma'lumot bo'lsa, xato xabari orqali uni o'g'irlash mumkin bo'lardi.
To'liq xatolik ma'lumotini olish uchun ikki narsa kerak:
- Tashqi skriptda
crossoriginatributi bo'lishi; - Uzoq server esa
Access-Control-Allow-OriginHTTP sarlavhasini yuborishi.
crossorigin atributining uch varianti bor:
crossoriginyo'q โ kirish taqiqlangan (to'liq xato ma'lumoti berilmaydi);crossorigin="anonymous"โ serverAccess-Control-Allow-Originyuborsa, kirishga ruxsat. Cookie va autentifikatsiya ma'lumotlari yuborilmaydi;crossorigin="use-credentials"โ server maxsus sarlavhalar yuborsa, kirishga ruxsat. Cookie va autentifikatsiya ma'lumotlari ham yuboriladi.
<script crossorigin="anonymous" src="https://another-site.com/script.js"></script>
crossorigin="anonymous" yetarli. Bu esa window.onerrorda to'liq xato tafsilotlarini olish imkonini beradi โ bu, ayniqsa, ishlab chiqarishda (production) xatolarni kuzatuvchi tizimlar (Sentry va h.k.) uchun muhim.Resurs holatini kuzatish (amaliy misol)
Yuqoridagi bilimlarni birlashtirib, resursni yuklab, uni kuzatuvchi umumiy funksiya yozamiz. Bu funksiya skriptni yuklaydi va callback orqali natijani (xato yoki muvaffaqiyat) qaytaradi:
function loadScript(src, callback) {
let script = document.createElement('script');
script.src = src;
document.head.append(script);
script.onload = () => callback(null, script);
script.onerror = () => callback(new Error('Skript yuklashda xatolik: ' + src));
}
// ishlatish:
loadScript('https://cdn.jsdelivr.net/npm/lodash@4.17.21/lodash.min.js', function(error, script) {
if (error) {
// xatolikni qayta ishlash
alert(error.message);
} else {
// skript muvaffaqiyatli yuklandi
alert('Yuklandi: ' + script.src);
}
});
Bu Node.js uslubidagi (error-first) callback pattern โ birinchi argument xato, ikkinchisi natija. Uni Promise'ga o'rab, async/await bilan ishlatish ham mumkin:
function loadScriptPromise(src) {
return new Promise((resolve, reject) => {
let script = document.createElement('script');
script.src = src;
document.head.append(script);
script.onload = () => resolve(script);
script.onerror = () => reject(new Error('Xatolik: ' + src));
});
}
// ishlatish:
loadScriptPromise('https://cdn.jsdelivr.net/npm/lodash@4.17.21/lodash.min.js')
.then(script => alert('Yuklandi'))
.catch(error => alert(error.message));
Promise.all bilan hammasini parallel yuklab, hammasi tayyor bo'lishini kutish mumkin.Xulosa
Tashqi resurslarni yuklashni kuzatish:
- Rasmlar (
img), tashqi stillar, skriptlar va boshqa resurslarloadvaerrorhodisalarini generatsiya qiladi; loadโ resurs muvaffaqiyatli yuklanganda;errorโ yuklashda xatolik bo'lganda;- Istisno โ
<iframe>: u har doimloadni generatsiya qiladi (muvaffaqiyat/xatolikdan qat'i nazar); load/onerrorfaqat yuklashni kuzatadi โ skript ichidagi ishlash xatolarini ko'rmaydi (buning uchunwindow.onerror).
Crossorigin (bir manba) siyosati: boshqa domendan yuklangan skript xatoliklarining to'liq ma'lumotini olish uchun crossorigin atributi va server tomonida Access-Control-Allow-Origin sarlavhasi kerak. crossorigin="anonymous" odatda yetarli.
Promise.all bilan boshqarish. Bu texnikalar zamonaviy SPA (Single Page Application) ilovalarida asos hisoblanadi.