ebSkola

12.4 Front-end + API integrācija

Stundas uzdevums: Savienot HTML/CSS/JS priekšgalu ar Flask backend, lai izveidotu pilnvērtīgu lietotni.

SR 2.4.7. Lietotāja saskarne SR 2.4.11. Standartizētas bibliotēkas un API

70 min plāns: Teorija un paraugs (~10 min) · 1. uzdevums (~15 min) - izsauc savu API ar fetch · 2. uzdevums (~25 min) - parādi datus tabulā · 3. uzdevums (~20 min) - nosūti formu ar POST. Papildu uzdevumu sāc tikai tad, ja pārējie trīs ir gatavi.

Pirms sāc: palaid savu 12.3 stundas Flask serveri un atstāj to darbojamies. HTML failu atver otrā cilnē - abi strādās vienlaikus.

Teorija: fetch() un async - pārlūks runā ar serveri

JavaScript fetch() API ļauj nosūtīt HTTP pieprasījumus no pārlūka uz serveri.

// GET pieprasījums
async function ielādētRezultātus() {
  const r = await fetch("http://localhost:5000/api/rezultati");
  if (!r.ok) {
    console.error("Kļūda:", r.status);
    return;
  }
  const dati = await r.json();
  console.log(dati);
}

// POST ar JSON
async function pievienot(vards, punkti) {
  const r = await fetch("/api/rezultati", {
    method: "POST",
    headers: { "Content-Type": "application/json" },
    body: JSON.stringify({ vards, punkti })
  });
  return await r.json();
}

CORS: Ja frontend ir uz http://localhost:8080, bet backend uz :5000, pārlūks bloķē pieprasījumus drošības dēļ. Risinājums Flask pusē:

from flask_cors import CORS
CORS(app)  # atļauj visiem; produkcijā konkrēti norādi atļautos domēnus

Praktiskie uzdevumi

1. uzdevums -

Izsauc savu API ar fetch

Beigās pārlūks pats paņems datus no tava servera.

  1. Izveido failu index.html ar tukšu <script> bloku.
  2. Uzraksti async function ielade() {.
  3. Ieraksti tajā const r = await fetch("http://localhost:5000/api/rezultati");.
  4. Pievieno const dati = await r.json(); un console.log(dati);.
  5. Izsauc funkciju un atver lapu pārlūkā.
  6. Atver F12 konsoli un pārbaudi, vai dati parādījās.

Gatavs, kad: konsolē redzams masīvs ar rezultātiem, nevis kļūdas paziņojums.

2. uzdevums -

Parādi datus tabulā

Beigās dati būs redzami lapā, nevis tikai konsolē.

  1. Pievieno HTML failā <table id="saraksts"></table>.
  2. Izveido ciklu for (const r of dati) {.
  3. Uzbūvē katrai rindai HTML tekstu ar vārdu un punktiem.
  4. Ieliec to tabulā ar document.getElementById("saraksts").innerHTML = ....
  5. Pārlādē lapu un pārbaudi tabulu.
  6. Pievieno pārbaudi if (!r.ok) ar paziņojumu par kļūdu.
  7. Apturi serveri un pārlādē lapu, lai redzētu kļūdas apstrādi.

Gatavs, kad: ar ieslēgtu serveri tabula ir aizpildīta, bet ar izslēgtu parādās tavs kļūdas paziņojums.

3. uzdevums -

Nosūti formu ar POST

Beigās lietotājs varēs pievienot rezultātu tieši no lapas.

  1. Pievieno formu ar diviem ievades laukiem un pogu.
  2. Pārtver formas nosūtīšanu ar e.preventDefault();.
  3. Izsauc fetch ar method: "POST".
  4. Pievieno galveni headers: {"Content-Type": "application/json"}.
  5. Nosūti datus ar body: JSON.stringify({vards, punkti}).
  6. Izsauc pēc tam ielade(), lai tabula atjaunotos.
  7. Pieraksti vienu secinājumu: kāpēc bez preventDefault() lapa pārlādējas.

Gatavs, kad: pēc pogas nospiešanas jaunais rezultāts parādās tabulā, un lapa nepārlādējas.

Papildu uzdevums - Atrisini CORS kļūdu

Ja pamatdarbs ir gatavs, uzzini, kāpēc pārlūks bloķē svešus pieprasījumus.

  1. Atver HTML failu no diska un mēģini izsaukt API.
  2. Izlasi konsolē kļūdu, kurā minēts vārds CORS.
  3. Instalē serverī pip install flask-cors.
  4. Pievieno kodam CORS(app).
  5. Pārlādē lapu un pārbaudi, ka kļūda pazuda.

Gatavs, kad: pirms labojuma konsolē ir CORS kļūda, pēc tā dati ielādējas.

Biežākās kļūdas

  • CORS bloķē: Pārliecinies, ka frontend un backend ir uz tā paša domēna vai izmanto Flask-CORS.
  • Forma pārlādē lapu: Aizmirsts e.preventDefault() - vienmēr pirmais POST handler-ī.
  • JSON nav valid: Ja serveris atgriež HTML kļūdu lapu, r.json() mestu izņēmumu.

Koda piemērs

<!-- index.html -->
<form id="forma">
  <input id="vards" placeholder="Vārds">
  <input id="punkti" type="number" placeholder="Punkti">
  <button>Saglabāt</button>
</form>
<table id="saraksts"></table>

<script>
async function atjaunot() {
  const dati = await (await fetch("/api/rezultati")).json();
  document.getElementById("saraksts").innerHTML =
    dati.map(r => `<tr><td>${r.vards}</td><td>${r.punkti}</td></tr>`).join("");
}

document.getElementById("forma").onsubmit = async (e) => {
  e.preventDefault();
  await fetch("/api/rezultati", {
    method: "POST",
    headers: {"Content-Type": "application/json"},
    body: JSON.stringify({
      vards: vards.value,
      punkti: parseInt(punkti.value)
    })
  });
  forma.reset();
  atjaunot();
};

atjaunot();
</script>
Lapa rāda dinamisku tabulu;
Forma pievieno datus;
Tabula atjaunojas automātiski.