12.4 Front-end + API integrācija
Stundas uzdevums: Savienot HTML/CSS/JS priekšgalu ar Flask backend, lai izveidotu pilnvērtīgu lietotni.
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.
- Izveido failu
index.htmlar tukšu<script>bloku. - Uzraksti
async function ielade() {. - Ieraksti tajā
const r = await fetch("http://localhost:5000/api/rezultati");. - Pievieno
const dati = await r.json();unconsole.log(dati);. - Izsauc funkciju un atver lapu pārlūkā.
- 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ē.
- Pievieno HTML failā
<table id="saraksts"></table>. - Izveido ciklu
for (const r of dati) {. - Uzbūvē katrai rindai HTML tekstu ar vārdu un punktiem.
- Ieliec to tabulā ar
document.getElementById("saraksts").innerHTML = .... - Pārlādē lapu un pārbaudi tabulu.
- Pievieno pārbaudi
if (!r.ok)ar paziņojumu par kļūdu. - 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.
- Pievieno formu ar diviem ievades laukiem un pogu.
- Pārtver formas nosūtīšanu ar
e.preventDefault();. - Izsauc
fetcharmethod: "POST". - Pievieno galveni
headers: {"Content-Type": "application/json"}. - Nosūti datus ar
body: JSON.stringify({vards, punkti}). - Izsauc pēc tam
ielade(), lai tabula atjaunotos. - 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.
- Atver HTML failu no diska un mēģini izsaukt API.
- Izlasi konsolē kļūdu, kurā minēts vārds
CORS. - Instalē serverī
pip install flask-cors. - Pievieno kodam
CORS(app). - 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>
Forma pievieno datus;
Tabula atjaunojas automātiski.