IlmHamroh
JavaScript Full-stack/9-qism. JavaScript brauzerda va debugging24/29-dars19 daqiqa
Mundarija (35)

JavaScript FormData: butun formani bitta qatorda yig'ish

Qisqacha: FormData butun formani bitta qatorda, aynan brauzer serverga yuboradigan ko'rinishda yig'adi: new FormData(forma). Belgilanmagan checkbox, disabled va nomsiz maydonlar unga kirmaydi; oddiy obyekt — Object.fromEntries, checkbox guruhi — getAll. Qaysi tugma bosilganini event.submitter aytadi, formani koddan esa requestSubmit() bilan yuboring — u tekshiruvni ham, submit hodisasini ham o'tkazadi.

Bu darsda

  • new FormData(forma) bilan butun formani yig'asiz va unga nima kirishini aniq bilasiz.
  • Object.fromEntries va getAll bilan ma'lumotni qulay obyektga aylantirasiz.
  • Fayl maydonidan tanlangan faylni olasiz.
  • event.submitter bilan qaysi tugma bosilganini aniqlaysiz.
  • requestSubmit() va eski submit() farqini tushuntira olasiz.

Oldin bilishingiz kerak: input va change: jonli tekshirish, Forma qiymatlarini o'qish va submit, Obyekt bo'ylab yurish, Fayl yuklash maydoni.

1. Nega bu kerak?

Forma qiymatlarini o'qish darsidagi to'liq bron misolini eslang. Har maydon uchun bitta qator yozdik: ism: el.ism.value.trim(), telefon: el.telefon.value — jami beshta qator. Endi «Bahor» yetkazib berish formasini tasavvur qiling: 15 ta maydon, qo'shimchalar uchun 6 ta checkbox, izoh, manzil. 15 qator kod — va ulardan bittasini unutib qo'yish hech gap emas.

Unutilgan maydon xatoni ham bermaydi. Mehmon "Qalampirsiz" ni belgiladi, oshpaz Rustam aka esa buni bilmay qoladi.

Brauzer esa forma yuborilganda hech narsani unutmaydi: barcha name li maydonlarni o'zi yig'adi. JavaScript'da aynan shu yig'ish mexanizmidan foydalanish mumkin — bu FormData (forma ma'lumoti).

Hayotdan o'xshatish: choyxonadagi buyurtma varaqasi. Ofitsiant Otabek har stolga borib "osh nechta, choy nechta?" deb alohida so'ramaydi. U to'ldirilgan varaqani oladi va oshxonaga butunligicha beradi. FormData — o'sha varaqa.

2. new FormData(forma)

2.1 Birinchi yig'ish

html
<form id="bron" action="https://example.com/bron" method="post">
  <label>Ism <input name="ism" value="Ali"></label>
  <label>Kishi <input name="odam" type="number" value="4"></label>
  <fieldset>
    <legend>Joy</legend>
    <label><input type="radio" name="joy" value="zal"> Zal</label>
    <label>
      <input type="radio" name="joy" value="ayvon" checked> Ayvon
    </label>
  </fieldset>
  <label><input type="checkbox" name="rozi" checked> Roziman</label>
  <label><input type="checkbox" name="sms"> SMS eslatma</label>
  <label>Stol <input name="stol" value="7" disabled></label>
  <label>Izoh <input value="nomsiz maydon"></label>
  <button type="submit" name="amal" value="bron">Bron qilish</button>
</form>
<script>
  const forma = document.querySelector("#bron");
  const malumot = new FormData(forma);
  console.log(malumot);

  for (const [nom, qiymat] of malumot) {
    console.log(nom, "=", qiymat);
  }
</script>

Konsolda:

text
FormData {}
ism = Ali
odam = 4
joy = ayvon
rozi = on

Bu kod sahifa ochilishi bilan ishlaydi — tugmani bosish shart emas. Bossangiz, pastda yashil " Forma tekshiruvdan o'tdi" yozuvi chiqadi: bu blokda submit tinglovchisi yo'q (Forma qiymatlarini o'qish darsidagi yashil yozuv).

Birinchi qatorga hayron bo'lmang: FormData {} — bo'sh obyektga o'xshaydi, lekin ichi to'la. Chrome konsoli ham uni shunday ko'rsatadi, chunki ma'lumot oddiy xususiyatlarda emas, ichki ro'yxatda saqlanadi. Ichini ko'rish uchun uni for...of bilan aylanib chiqamiz. Har qadamda [nom, qiymat] juftligi keladi — Obyekt bo'ylab yurish darsidagi Object.entries bilan bir xil shakl.

2.2 Nima kiradi, nima kirmaydi

Formada sakkizta element bor edi, FormData da esa to'rt juftlik. Qolganlari qayerda?

Element Kirdimi Nega
ism, odam Ha name bor, qiymati bor
joy Ha, faqat ayvon Radio guruhidan faqat tanlangani
rozi Ha, on Belgilangan checkbox
sms Yo'q Belgilanmagan checkbox umuman ketmaydi
stol Yo'q disabled
"Izoh" Yo'q name yo'q
Tugma Yo'q Tugma faqat o'zi bosilganda ketadi

Bu qoidalarni siz allaqachon bilasiz — Forma qanday ishlaydi va Maydon holatlari darslarida brauzer serverga aynan shunday yuborardi. FormData yangi qoida o'ylab topmaydi: u serverga ketadigan narsaning aniq nusxasi. Shuning uchun JavaScript'dagi ma'lumot va serverga ketadigan ma'lumot hech qachon farq qilmaydi.

Tekshirib ko'ring: sms checkbox'ini belgilab, natijani "Tahrirlab ko'rish" bilan qayta ishga tushirsangiz, konsolda nechta juftlik chiqadi va beshinchisi qanday bo'ladi?

Javob

Beshta. Beshinchisi — sms = on. Checkbox'da value atributi yo'q, shuning uchun standart qiymat on ketadi. sms HTML'da rozi dan keyin turgani uchun ro'yxatda ham undan keyin keladi — tartib doim HTML'dagi tartib.

2.3 Bitta qiymatni olish va o'zgartirish

FormData ning metodlari Map'ga o'xshash — kursda keyinroq o'rganamiz, hozir bilish shart emas. Eng kerakli to'rttasi:

Metod Nima qiladi
get("nom") Birinchi qiymat; nom yo'q bo'lsa — null
has("nom") Shu nom bormi: true / false
set("nom", qiymat) Qiymatni almashtiradi (yoki qo'shadi)
append("nom", qiymat) Yana bitta qiymat qo'shadi, eskisini o'chirmaydi

set va append formaning o'zini o'zgartirmaydi — faqat FormData nusxasini. Masalan, serverga qo'shimcha ma'lumot jo'natish kerak bo'lsa: malumot.set("manba", "sayt").

FormData ni formasiz ham yaratish mumkin: new FormData() — bo'sh "varaqa", unga append bilan o'zingiz yozasiz. Bu sahifada forma yo'q, lekin ma'lumotni forma shaklida jo'natish kerak bo'lganda qo'l keladi — masalan, "Sevimlilarga qo'shish" tugmasi bosilganda taom nomini serverga yuborish.

2.4 formdata hodisasi

Formada yana bitta kam tanilgan hodisa bor — formdata. U brauzer formadan FormData yig'ayotgan har safar keladi: siz new FormData(forma) deb yozganingizda ham, forma oddiy yo'l bilan yuborilayotganda ham. Hodisa obyektidagi event.formData — yig'ilayotgan ro'yxatning o'zi, unga qiymat qo'shish mumkin:

html
<form id="bron">
  <label>Ism <input name="ism" value="Ali"></label>
</form>
<script>
  const forma = document.querySelector("#bron");
  forma.addEventListener("formdata", (event) => {
    event.formData.set("manba", "sayt");
  });
  console.log(Object.fromEntries(new FormData(forma)));
</script>

Konsolda:

text
{ism: 'Ali', manba: 'sayt'}

manba formada yo'q, lekin FormData da bor. Bu "har yuborishga bitta maydon qo'sh" degan qoidani bitta joyda yozish uchun qulay. Kundalik ishda kam kerak bo'ladi — borligini bilib qo'yish yetarli.

3. Object.fromEntries — oddiy obyektga

FormData ni aylanib chiqish noqulay, get bilan esa har maydonni nomma-nom so'rash kerak. Ko'pincha bizga oddiy obyekt kerak. Uni Obyekt bo'ylab yurish darsidagi Object.fromEntries bitta qatorda beradi: u [nom, qiymat] juftliklarini obyektga aylantiradi.

html
<form id="bron">
  <label>Ism <input name="ism" value="Ali"></label>
  <label>Kishi <input name="odam" type="number" value="4"></label>
  <label>Vaqt <input name="vaqt" type="time" value="19:00"></label>
</form>
<script>
  const forma = document.querySelector("#bron");
  const malumot = new FormData(forma);
  console.log(malumot.get("ism"), malumot.has("odam"));
  console.log(malumot.get("telefon"));

  const bron = Object.fromEntries(malumot);
  console.log(bron);
  bron.odam = Number(bron.odam);
  console.log(bron);
</script>

Konsolda:

text
Ali true
null
{ism: 'Ali', odam: '4', vaqt: '19:00'}
{ism: 'Ali', odam: 4, vaqt: '19:00'}

Uchinchi qatorga qarang: odam: '4' — qo'shtirnoq ichida, ya'ni satr. FormData ichida hamma qiymat satr (fayldan tashqari), xuddi input.value kabi. Son kerak bo'lsa, o'zingiz aylantirasiz — to'rtinchi qatorda shunday qildik.

Forma qiymatlarini o'qish darsidagi besh qatorli obyekt yig'ish endi ikki qator: new FormData va Object.fromEntries. Maydon qo'shilsa, JavaScript'ga tegish shart emas — u HTML'dan o'zi olinadi.

4. Bir nomli bir nechta qiymat: getAll

4.1 fromEntries ning tuzog'i

Forma qiymatlarini o'qish darsidagi 3-mashqni eslang: bir xil name li checkbox'lar. FormData ularning har birini alohida juftlik qilib yig'adi. Lekin obyektda bitta kalit faqat bitta qiymatga ega bo'la oladi:

html
<form id="bron">
  <fieldset>
    <legend>Qo'shimchalar</legend>
    <label>
      <input type="checkbox" name="qoshimcha" value="non" checked> Non
    </label>
    <label>
      <input type="checkbox" name="qoshimcha" value="salat"> Salat
    </label>
    <label>
      <input type="checkbox" name="qoshimcha" value="choy" checked>
      Choy
    </label>
  </fieldset>
</form>
<script>
  const malumot = new FormData(document.querySelector("#bron"));
  console.log(Object.fromEntries(malumot));
  console.log(malumot.get("qoshimcha"));
  console.log(malumot.getAll("qoshimcha"));
  console.log(malumot.getAll("yoq"));
</script>

Konsolda:

text
{qoshimcha: 'choy'}
non
(2) ['non', 'choy']
(0) []

Uchala natijani solishtiring:

  • Object.fromEntries — faqat oxirgisi qoldi, non yo'qoldi. Xato ham, ogohlantirish ham yo'q.
  • get — faqat birinchisi.
  • getAll — hammasi, massiv bo'lib. Hech biri belgilanmagan bo'lsa — bo'sh massiv ((0) []), null emas. Shuning uchun natijani for...of bilan xavfsiz aylanish mumkin.

getAll Forma qiymatlarini o'qish darsidagi RadioNodeList muammosini ham yo'q qiladi: checkbox bitta bo'lsa ham, uchta bo'lsa ham, doim massiv keladi. multiple li select da ham xuddi shunday ishlaydi.

O'zingiz to'ldiring (metod nomini yozing):

  • Belgilangan barcha qo'shimchalar, massiv bo'lib — malumot.("qoshimcha")
  • Faqat birinchi belgilangani — malumot.("qoshimcha")
  • Butun forma oddiy obyekt bo'lib — Object.(malumot)

4.2 Retsept: obyekt + ro'yxatlar

Amalda ikkalasi birga ishlatiladi:

js
const malumot = new FormData(forma);
const bron = Object.fromEntries(malumot);
bron.odam = Number(bron.odam);
bron.qoshimcha = malumot.getAll("qoshimcha");

Oddiy maydonlar fromEntries dan keladi, ko'p qiymatlilari getAll bilan ustidan yoziladi, sonlar Number bilan aylantiriladi. Bu uch qator 20 maydonli formada ham uch qatorligicha qoladi.

Tekshirib ko'ring: Formada <select name="taomlar" multiple> bor, osh va manti tanlangan. Object.fromEntries(malumot).taomlar va malumot.getAll("taomlar") nima beradi?

Javob

'manti' (faqat oxirgi tanlangan) va ['osh', 'manti']. Ko'p tanlovli select ham bir nomli bir nechta juftlik yuboradi — checkbox'lar bilan bir xil holat.

5. Fayl maydoni

Fayl yuklash maydoni darsida <input type="file"> ni ko'rgan edik. FormData uni ham yig'adi, lekin qiymat satr emas — File (fayl) obyekti:

html
<form id="sharh">
  <label for="rasm">Taom rasmi (ixtiyoriy)</label>
  <input id="rasm" name="rasm" type="file" accept="image/*">
  <button type="submit">Yuborish</button>
</form>
<script>
  const forma = document.querySelector("#sharh");

  forma.addEventListener("submit", (event) => {
    event.preventDefault();
    const fayl = new FormData(forma).get("rasm");
    console.log(fayl);
    console.log(fayl.name, fayl.size, fayl.type);
    if (fayl.size === 0) {
      console.log("Rasm tanlanmagan");
    }
  });
</script>

Avval faylsiz «Yuborish» ni bosing. Konsolda File {}, keyin bo'sh nom bilan 0 application/octet-stream va "Rasm tanlanmagan" chiqadi. Keyin kompyuteringizdan biror rasm tanlab, yana bosing — fayl nomi, hajmi baytlarda va turi (masalan image/jpeg) chiqadi.

Ikki muhim fakt:

  • Fayl tanlanmasa ham get null bermaydi. U nomi bo'sh va hajmi 0 bo'lgan "bo'sh fayl" qaytaradi. Shuning uchun "fayl bormi?" savoliga fayl.size === 0 javob beradi, fayl === null emas.
  • File obyektining ichini konsol File {} deb ko'rsatadi — kerakli xususiyatlarni (name, size, type) alohida chiqaring.

Fayl ham FormData ning ichida qoladi. Uni keyinroq fetch bilan jo'natganda brauzer fayl uchun kerakli multipart/form-data shaklini o'zi tanlaydi — Fayl yuklash maydoni darsidagi enctype ni qo'lda yozish shart bo'lmaydi. Faylning o'zi bilan ishlash (oldindan ko'rsatish, o'lchamini tekshirish) — File va Blob darsida.

Tekshirib ko'ring: Rasm maydonida multiple atributi bor va mehmon uchta rasm tanladi. malumot.get("rasm") va malumot.getAll("rasm") nima beradi?

Javob

get — faqat birinchi rasm (File), getAll — uchala rasm massivda. multiple li fayl maydoni ham checkbox'lar kabi bir nomli bir nechta juftlik yuboradi. Shuning uchun bu yerda ham getAll kerak.

6. Qaysi tugma bosildi: event.submitter

6.1 Ikki tugmali forma

Brauzer validatsiyasi darsida formada ikkita tugma bor edi: «Bron qilish» va tekshiruvsiz «Qoralama sifatida saqlash» (formnovalidate). Ikkalasi ham bitta submit hodisasini chiqaradi. Qaysi biri bosilganini SubmitEvent (yuborish hodisasi) obyektining submitter xususiyati aytadi:

html
<form id="bron" action="https://example.com/bron" method="post">
  <label>Ism <input name="ism" required></label>
  <button type="submit" name="amal" value="bron">Bron qilish</button>
  <button type="submit" name="amal" value="qoralama"
          formnovalidate>Qoralama</button>
</form>
<script>
  const forma = document.querySelector("#bron");

  forma.addEventListener("submit", (event) => {
    event.preventDefault();
    console.log("Bosildi:", event.submitter.value);
    const bilan = new FormData(forma, event.submitter);
    const siz = new FormData(forma);
    console.log(Object.fromEntries(bilan), Object.fromEntries(siz));
  });
</script>

Ismni bo'sh qoldirib «Qoralama» ni bosing. Konsolda ikki qator chiqadi:

text
Bosildi: qoralama
{ism: '', amal: 'qoralama'} {ism: ''}

«Bron qilish» ni bo'sh ism bilan bossangiz — required to'xtatadi, formnovalidate esa faqat o'z tugmasini tekshiruvdan ozod qildi. Ism yozib, «Bron qilish» ni bosing — Bosildi: bron.

Uch narsaga e'tibor bering:

  • event.submitter — bosilgan tugma elementi. Undan value, name, hatto textContent ni o'qish mumkin.
  • new FormData(forma) tugmani o'zi qo'shmaydi. Ikkinchi argument — new FormData(forma, event.submitter) — tugmaning name=value juftligini ham qo'shadi, xuddi brauzer serverga yuborgandek.
  • Ismga yozib, maydonning ichida Enter ni bossangiz ham submitter bor: "yashirin yuborish" formaning birinchi tugmasini bosadi, ya'ni bron.

event.submitter 2022-yildan barcha asosiy brauzerlarda bor. FormData ning ikkinchi argumenti yangiroq: 2023-yil aprelidan hamma brauzerda, 2025-yil oktabridan "keng tarqalgan" Baseline (web-features ma'lumoti).

6.2 Ikki marta bosishdan himoya

Sekin internetda mehmon «Bron qilish» ni bosadi, hech narsa bo'lmayotgandek tuyuladi — yana bosadi. Serverga ikkita bron ketadi. Yechim: yuborish davomida tugmani vaqtincha o'chirish. Serverni hozircha setTimeout bilan taqlid qilamiz:

html
<form id="bron" action="https://example.com/bron" method="post">
  <label>Ism <input name="ism" value="Ali" required></label>
  <button type="submit">Bron qilish</button>
</form>
<p id="holat"></p>
<script>
  const forma = document.querySelector("#bron");
  const holat = document.querySelector("#holat");
  let soni = 0;

  forma.addEventListener("submit", (event) => {
    event.preventDefault();
    const tugma = event.submitter;
    tugma.disabled = true;
    soni = soni + 1;
    console.log(`${soni}-so'rov yuborildi`);
    holat.textContent = "Yuborilmoqda...";

    setTimeout(() => {
      holat.textContent = "Bron qabul qilindi.";
      tugma.disabled = false;
    }, 1500);
  });
</script>

Tugmani tez-tez uch marta bosing. Konsolda bitta 1-so'rov yuborildi chiqadi: birinchi bosishdan keyin tugma disabled, qolgan bosishlar hech narsa qilmaydi. Bir yarim soniyadan keyin tugma yana faol. input va change darsidagi ogohlantirishni eslang: tugmani "forma to'liq emas" deb o'chirish yomon, yuborish paytida o'chirish esa o'rinli. Haqiqiy server javobini kutish — fetch bilan ma'lumot yuborish darsida.

Tekshirib ko'ring: Tugma o'chirilgach, mehmon ism maydonida Enter ni bossa, ikkinchi so'rov ketadimi?

Javob

Yo'q. "Yashirin yuborish" formaning birinchi yuborish tugmasini bosadi. U disabled bo'lsa, brauzer formani umuman yubormaydi — submit hodisasi ham kelmaydi. Shuning uchun bitta tugmani o'chirish ikkala yo'lni ham yopadi.

7. Koddan yuborish: requestSubmit()

7.1 Ctrl + Enter bilan yuborish

Ba'zan formani tugmasiz yuborish kerak: izoh maydonida Ctrl + Enter bosilganda, filtr ro'yxatidan tanlov o'zgarganda. Buning uchun formada requestSubmit() (yuborishni so'rash) metodi bor. Zamonaviy forma imkoniyatlari darsida va'da qilgan edik — mana u:

html
<form id="izoh-forma" action="https://example.com/izoh" method="post">
  <label for="izoh">Izoh (Ctrl + Enter — yuborish)</label>
  <textarea id="izoh" name="izoh" rows="3" required></textarea>
  <button type="submit">Yuborish</button>
</form>
<script>
  const forma = document.querySelector("#izoh-forma");

  forma.elements.izoh.addEventListener("keydown", (event) => {
    const tugmasi = event.ctrlKey || event.metaKey;
    if (event.key === "Enter" && tugmasi) {
      forma.requestSubmit();
    }
  });

  forma.addEventListener("submit", (event) => {
    event.preventDefault();
    console.log("Yuborildi:", forma.elements.izoh.value);
  });
</script>

Izohni bo'sh qoldirib Ctrl + Enter ni bosing (Mac'da Cmd + Enter) — brauzerning "maydonni to'ldiring" pufagi chiqadi, konsol jim. "Osh juda mazali" deb yozib, yana bosing — konsolda Yuborildi: Osh juda mazali. Klaviatura qismi — Klaviatura hodisalari darsidan tanish.

requestSubmit() tugma bosilgandek ishladi: avval brauzer tekshiruvi, keyin submit hodisasi va sizning tinglovchingiz. Bitta farq bor: tugma bosilmagani uchun event.submitter — null. Kerak bo'lsa, tugmani argument qilib bering: forma.requestSubmit(tugma). Argument shu formaning yuborish tugmasi bo'lishi shart, aks holda:

text
Uncaught TypeError: Failed to execute 'requestSubmit' on 'HTMLFormElement': The specified element is not a submit button.

Tarjimasi: "HTMLFormElement da requestSubmit ni bajarib bo'lmadi: ko'rsatilgan element yuborish tugmasi emas."

7.2 Eski submit() — nega ishlatmaymiz

Formada submit() metodi ham bor va u ancha eski. Ko'p eski kodda uchraydi, shuning uchun farqini bilish kerak:

requestSubmit() submit()
Brauzer tekshiruvi (required, pattern) Ha Yo'q — chetlab o'tadi
submit hodisasi (tinglovchingiz) Ha Yo'q — chaqirilmaydi
Qayerga ketadi Tinglovchi to'xtatmasa, action ga Darhol action ga

submit() sizning submit tinglovchingizni ham, preventDefault ni ham, required ni ham chetlab o'tib, sahifani to'g'ridan-to'g'ri action manziliga olib ketadi. Shu sabab bu darsda uni jonli oynada ko'rsatmaymiz. requestSubmit() 2022-yil sentabridan barcha asosiy brauzerlarda bor va 2025-yil martidan "keng tarqalgan" Baseline — uni bemalol ishlating.

Tekshirib ko'ring: Eski kodda forma.submit() turibdi va uni requestSubmit() ga almashtirdingiz. Shundan keyin forma yuborilmay qoldi. Ehtimoliy sabab nima?

Javob

Formada xatoli maydon bor. Eski submit() tekshiruvni chetlab o'tardi — xato hech qachon ko'rinmasdi va server noto'g'ri ma'lumot olardi. requestSubmit() esa brauzer tekshiruvini bajaradi va xatoli formani to'xtatadi. Ya'ni almashtirish yangi xato yaratmadi — eski, yashirin xatoni ochib berdi. Ikkinchi ehtimol: submit tinglovchisida preventDefault() bor, eski submit() uni chetlab o'tardi.

7.3 Bonus: URLSearchParams — URL'dagi ko'rinish

Son, sana, vaqt va rang maydonlari darsida method="get" forma qiymatlarni URL'ga ?ism=Ali&odam=4 ko'rinishida yozganini ko'rgan edik. FormData dan aynan shu satrni olish mumkin:

html
<form id="bron">
  <label>Ism <input name="ism" value="Ali Valiyev"></label>
  <label>Kishi <input name="odam" type="number" value="4"></label>
</form>
<script>
  const malumot = new FormData(document.querySelector("#bron"));
  console.log(new URLSearchParams(malumot).toString());
</script>

Konsolda:

text
ism=Ali+Valiyev&odam=4

URLSearchParams — URL'ning ? dan keyingi qismi bilan ishlaydigan obyekt. Uni URL va URLSearchParams darsida to'liq o'rganamiz. Bo'sh joy + ga aylandi — URL'da shunday yoziladi. Faylli formada esa bu usul yaramaydi: fayl o'rniga [object File] degan ma'nosiz matn chiqadi.

8. Hujumchi nigohi

FormData brauzer yuboradigan narsaning nusxasi. Demak, hujumchi brauzerda nimani o'zgartirsa, FormData da ham o'sha bo'ladi.

1. Yashirin maydonga ishonish. Ba'zi saytlar narxni formaga <input type="hidden" name="narx" value="35000"> qilib qo'yadi. Hujumchi DevTools'da value="1" deb yozadi — FormData ham, server ham 1 so'm oladi. Qarshi chora: narx, chegirma, foydalanuvchi roli kabi narsalar formadan olinmaydi. Server taom nomini oladi va narxni o'z bazasidan o'qiydi.

2. Botlar va "asal idishi". Forma xavfsizligi darsidagi veb_sayt maydoni (asal-idish) halol mehmonga ko'rinmaydi, botlar esa uni to'ldiradi. JavaScript ham uni tekshirib, keraksiz so'rovni umuman jo'natmasligi mumkin:

js
forma.addEventListener("submit", (event) => {
  event.preventDefault();
  const malumot = new FormData(forma);
  if (malumot.get("veb_sayt") !== "") {
    return; // bot: jimgina e'tiborsiz qoldiramiz
  }
  // ...halol mehmon: davom etamiz
});

Bu faqat qo'shimcha to'siq: aqlli bot JavaScript'ni umuman ishga tushirmay, to'g'ridan-to'g'ri serverga yozadi. Shuning uchun server ham veb_sayt ni tekshiradi (Forma xavfsizligi).

3. Kutilmagan maydonlar. Hujumchi formaga o'zi name="admin" value="true" maydonini qo'shishi mumkin. Object.fromEntries uni ham obyektga soladi. Server faqat o'zi kutgan maydonlarni oladi, qolganini tashlab yuboradi.

9. Ko'p uchraydigan xatolar

9.1 console.log(malumot) bo'sh ko'rinadi

FormData {} — xato emas. Tuzatish: for...of bilan aylaning yoki console.log(Object.fromEntries(malumot)).

9.2 Maydon FormData ga tushmadi

Sabab deyarli doim uchtadan biri: name yo'q, maydon disabled, yoki checkbox belgilanmagan. Tuzatish: name qo'shing; foydalanuvchi o'zgartira olmasligi kerak bo'lsa — disabled o'rniga readonly (input va change darsidagi jadval).

9.3 Checkbox'lardan bittasi yo'qoldi

Object.fromEntries bir nomli qiymatlardan faqat oxirgisini qoldiradi. Tuzatish: getAll.

9.4 Son satr bo'lib qoldi

bron.odam + 1 → "41". Tuzatish: Number(bron.odam) — FormData dagi hamma narsa satr.

9.5 submitter dan value o'qishda xato

text
Uncaught TypeError: Cannot read properties of null (reading 'value')

Tarjimasi: "null ning xususiyatlarini o'qib bo'lmaydi (value ni o'qishda)". Forma requestSubmit() bilan, tugmasiz yuborilgan — event.submitter null. Tuzatish: event.submitter?.value yoki requestSubmit(tugma).

9.6 Begona tugma

new FormData(forma, boshqaTugma) — tugma boshqa formaga tegishli:

text
Uncaught NotFoundError: Failed to construct 'FormData': The specified element is not owned by this form element.

Tarjimasi: "FormData ni yaratib bo'lmadi: ko'rsatilgan element shu formaga tegishli emas." Tuzatish: faqat shu formaning event.submitter ini bering.

10. Mashqlar

1-mashq (oson): Nima kiradi?

Forma:

html
<form>
  <input name="ism" value="Malika">
  <input name="telefon" value="+998 90 000 00 00" disabled>
  <input type="checkbox" name="sms" value="ha">
  <input type="checkbox" name="rozi" value="ha" checked>
  <input value="Toshkent">
  <button type="submit" name="amal" value="bron">Bron</button>
</form>

Object.fromEntries(new FormData(forma)) natijasini yozing.

Yechim

{ism: 'Malika', rozi: 'ha'}. telefon — disabled, sms — belgilanmagan, "Toshkent" maydonida name yo'q, tugma submitter sifatida berilmagan. rozi ning qiymati ha — value atributi yozilgan, shuning uchun on emas.

2-mashq (o'rta): Bron formasini qayta yozing

Forma qiymatlarini o'qish darsidagi to'liq bron misolini FormData bilan qayta yozing: obyekt Object.fromEntries bilan, odam — son, ism — probellarsiz. Natija o'sha-o'sha bo'lsin: {ism: 'Ali', telefon: '+998 90 000 00 00', odam: 4, vaqt: '19:00', joy: 'ayvon', rozi: 'on'} (endi rozi ham bor — FormData uni ham yig'adi).

Yechim

Faqat submit tinglovchisi o'zgaradi:

js
forma.addEventListener("submit", (event) => {
  event.preventDefault();
  const bron = Object.fromEntries(new FormData(forma));
  bron.ism = bron.ism.trim();
  bron.odam = Number(bron.odam);
  console.log(bron);

  javob.textContent =
    `${bron.ism}, ${bron.odam} kishilik stol ` +
    `soat ${bron.vaqt} ga band qilindi (${bron.joy}).`;
});

Beshta el.… qatori o'rniga bitta Object.fromEntries va ikki tuzatish. Formaga yangi maydon qo'shilsa, bu kod o'zgarmaydi.

3-mashq (qiyin): Qoralama va bron

Ikki tugmali forma yozing: ism (required), kishi soni (required, 1–20), izoh va «Bron qilish» / «Qoralama» (formnovalidate) tugmalari, ikkalasi name="amal".

  • «Bron qilish» → konsolga son bilan obyekt: {ism: 'Ali', odam: 4, izoh: ''}.
  • «Qoralama» → tekshiruvsiz, konsolga "Qoralama: 2 ta maydon to'ldirilgan" (bo'sh bo'lmagan qiymatlar soni, amal hisobga kirmaydi).

Ishora: tugmani event.submitter.value bilan ajrating; sanash uchun FormData ni for...of bilan aylaning.

Yechim
html
<form id="bron" action="https://example.com/bron" method="post">
  <label>Ism <input name="ism" value="Ali" required></label>
  <label>Kishi <input name="odam" type="number"
                      required min="1" max="20"></label>
  <label>Izoh <input name="izoh"></label>
  <button type="submit" name="amal" value="bron">Bron qilish</button>
  <button type="submit" name="amal" value="qoralama"
          formnovalidate>Qoralama</button>
</form>
<script>
  const forma = document.querySelector("#bron");

  forma.addEventListener("submit", (event) => {
    event.preventDefault();
    const malumot = new FormData(forma);

    if (event.submitter.value === "qoralama") {
      let toldirilgan = 0;
      for (const [nom, qiymat] of malumot) {
        if (qiymat !== "") {
          toldirilgan = toldirilgan + 1;
        }
      }
      console.log(`Qoralama: ${toldirilgan} ta maydon to'ldirilgan`);
      return;
    }

    const bron = Object.fromEntries(malumot);
    bron.odam = Number(bron.odam);
    console.log(bron);
  });
</script>

Kishi sonini bo'sh qoldirib «Qoralama» ni bosing — "Qoralama: 1 ta maydon to'ldirilgan" (faqat ism). 4 ni yozib yana bosing — 2 ta. «Bron qilish» bo'sh kishi soni bilan to'xtaydi, 4 bilan esa {ism: 'Ali', odam: 4, izoh: ''} chiqadi. amal hisobga kirmadi: FormData ni submitter siz yaratdik. for...of dagi nom ishlatilmadi — u faqat juftlikni ochish uchun turibdi.

4-mashq: Portfolio qadami — aloqa formasi FormData bilan

  1. aloqaFormasiniUla dagi submit tinglovchisini FormData + Object.fromEntries ga o'tkazing. Ism — probellarsiz.
  2. "Yuborish" davomida tugmani 800 ms ga o'chiring va rahmat xabarini shu vaqtdan keyin chiqaring — haqiqiy server javobiga tayyorgarlik.
  3. Konsolga butun obyektni chiqaring — serverga nima ketishini ko'rasiz.
  4. Commit: Aloqa: formani FormData bilan yig'.
Yechim

aloqaFormasiniUla ichidagi submit tinglovchisi (hisoblagich va email kodi o'zgarmaydi):

js
forma.addEventListener("submit", (event) => {
  event.preventDefault();
  const malumot = Object.fromEntries(new FormData(forma));
  malumot.ism = malumot.ism.trim();
  console.log("Aloqa:", malumot);

  const tugma = event.submitter;
  if (tugma !== null) {
    tugma.disabled = true;
  }
  natija.textContent = "Yuborilmoqda...";

  setTimeout(() => {
    natija.textContent =
      `Rahmat, ${malumot.ism}! Xabaringiz qabul qilindi. ` +
      "(Hozircha namuna: xabar hech qayerga yuborilmadi.)";
    forma.reset();
    hisobniYangila();
    if (tugma !== null) {
      tugma.disabled = false;
    }
  }, 800);
});

Konsolda taxminan shunday chiqadi:

text
Aloqa: {ism: 'Ali', email: 'ali@example.com', mavzu: 'savol', xabar: 'Salom!'}

tugma !== null tekshiruvi — forma requestSubmit() bilan yuborilsa ham kod buzilmasin. 800 ms — o'ylab topilgan "server vaqti"; fetch darsida u haqiqiy javob kutish bilan almashadi.

11. Real ishda

  • fetch bilan jo'natish. FormData ni to'g'ridan-to'g'ri so'rov tanasiga berish mumkin — fayllar bilan birga. Bu fetch bilan ma'lumot yuborish darsining asosiy usullaridan biri.
  • JSON API. Ko'p serverlar JSON kutadi: Object.fromEntries(new FormData(forma)) → obyekt → JSON.stringify (JSON asoslari). Bu yo'l ham shu darsdan boshlanadi.
  • Freymvorklar. React 19 dagi forma "action" lari (kursda alohida o'rganamiz, hozir bilish shart emas) funksiyaga to'g'ridan-to'g'ri FormData beradi. Bugungi bilim u yerda ham o'zgarishsiz ishlaydi.
  • Kod sharhida (code review) har maydon uchun alohida querySelector yozilgan uzun formani ko'rsangiz, birinchi taklif — FormData. Kod kamroq, unutilgan maydon esa umuman bo'lmaydi: yangi maydon HTML'ga qo'shilishi bilan ma'lumotga ham tushadi.
  • Intervyuda: "Formadagi barcha qiymatlarni qanday olasiz?", "submit() va requestSubmit() farqi?", "Checkbox guruhini qanday o'qiysiz?" — FormData, getAll va bugungi jadval.

Xulosa

  • new FormData(forma) — serverga ketadigan narsaning aniq nusxasi: name li, disabled bo'lmagan, belgilangan maydonlar.
  • Object.fromEntries(malumot) — oddiy obyekt; qiymatlar satr, sonni o'zingiz aylantirasiz.
  • Bir nomli bir nechta qiymat — faqat getAll; fromEntries oxirgisini, get birinchisini qoldiradi.
  • Fayl maydoni File beradi; tanlanmasa ham null emas — size === 0.
  • event.submitter — bosilgan tugma; new FormData(forma, event.submitter) uning qiymatini ham qo'shadi.
  • Koddan yuborish — requestSubmit(): tekshiruv va submit hodisasi bilan; eski submit() ikkalasini chetlab o'tadi.

Keyingi dars: Constraint Validation API — brauzer tekshiruvini JavaScript'dan o'qiymiz va xabarlarini nihoyat o'zbekcha qilamiz.

Manbalar

  • MDN: "FormData", "FormData() constructor" (submitter parametri), "FormData: getAll()" — developer.mozilla.org
  • MDN: "SubmitEvent: submitter", "HTMLFormElement: requestSubmit()" — developer.mozilla.org
  • web-features (Baseline): form (requestSubmit, SubmitEvent.submitter), xhr (FormData konstruktorining submitter argumenti) — 2026-10 holati
Ulashish:Telegram'da

Izohlar (0)

Izoh yozish uchun kiring.

  • Hozircha izoh yo'q. Birinchi bo'ling!
JavaScript FormData: butun formani bitta qatorda yig'ish — IlmHamroh