# Izdelava bančne aplikacije, 3. del: Metode pridobivanja in uporabe podatkov Pomislite na računalnik Enterprise v seriji Star Trek - ko kapitan Picard vpraša za stanje ladje, se informacije prikažejo takoj, brez da bi se celoten vmesnik ustavil in ponovno zgradil. Takšen nemoten pretok informacij je točno tisto, kar gradimo tukaj z dinamičnim pridobivanjem podatkov. Trenutno je vaša bančna aplikacija kot natisnjen časopis - informativna, a statična. Spremenili jo bomo v nekaj podobnega kot nadzorno središče pri NASA, kjer podatki neprekinjeno tečejo in se posodabljajo v realnem času, ne da bi prekinili uporabnikovo delo. Naučili se boste, kako asinhrono komunicirati s strežniki, obravnavati podatke, ki prispejo ob različnih časih, in surove informacije pretvoriti v nekaj smiselnega za vaše uporabnike. To je razlika med demo aplikacijo in programsko opremo, pripravljeno za produkcijo. ## Predhodni kviz [Predhodni kviz](https://ff-quizzes.netlify.app/web/quiz/45) ### Predpogoji Preden se lotite pridobivanja podatkov, poskrbite, da imate pripravljene naslednje komponente: - **Prejšnja lekcija**: Dokončajte [Obrazec za prijavo in registracijo](../2-forms/README.md) - gradili bomo na tej osnovi - **Lokalni strežnik**: Namestite [Node.js](https://nodejs.org) in [zaženite strežniški API](../api/README.md) za zagotavljanje podatkov o računih - **Povezava z API-jem**: Preverite povezavo s strežnikom s tem ukazom: ```bash curl http://localhost:5000/api # Expected response: "Bank API v1.0.0" ``` Ta hitri test zagotavlja, da vsi deli pravilno komunicirajo: - Preveri, ali Node.js pravilno deluje na vašem sistemu - Potrdi, da je vaš API strežnik aktiven in se odziva - Preveri, ali vaša aplikacija doseže strežnik (kot preverjanje radijske povezave pred misijo) --- ## Razumevanje pridobivanja podatkov v sodobnih spletnih aplikacijah Način, kako spletne aplikacije obravnavajo podatke, se je v zadnjih dveh desetletjih dramatično spremenil. Razumevanje te evolucije vam bo pomagalo ceniti, zakaj so sodobne tehnike, kot sta AJAX in Fetch API, tako močne in zakaj so postale bistvena orodja za spletne razvijalce. Raziskali bomo, kako so delovale tradicionalne spletne strani v primerjavi z dinamičnimi, odzivnimi aplikacijami, ki jih gradimo danes. ### Tradicionalne večstranske aplikacije (MPA) V zgodnjih dneh spleta je bil vsak klik podoben menjavi kanalov na starem televizorju - zaslon bi se zatemnil, nato pa počasi prikazal novo vsebino. To je bila realnost zgodnjih spletnih aplikacij, kjer je vsaka interakcija pomenila popolno ponovno gradnjo celotne strani. ```mermaid sequenceDiagram participant User participant Browser participant Server User->>Browser: Clicks link or submits form Browser->>Server: Requests new HTML page Note over Browser: Page goes blank Server->>Browser: Returns complete HTML page Browser->>User: Displays new page (flash/reload) ``` ![Delovni tok posodobitev v večstranski aplikaciji](../../../../translated_images/mpa.7f7375a1a2d4aa779d3f928a2aaaf9ad76bcdeb05cfce2dc27ab126024050f51.sl.png) **Zakaj je bil ta pristop okoren:** - Vsak klik je pomenil ponovno gradnjo celotne strani - Uporabniki so bili prekinjeni s tistimi nadležnimi utripajočimi stranmi - Vaša internetna povezava je delala nadure, saj je večkrat prenašala isti glavi in nogi - Aplikacije so se zdele bolj kot brskanje po omari z dokumenti kot uporaba programske opreme ### Sodobne enostranske aplikacije (SPA) AJAX (Asynchronous JavaScript and XML) je popolnoma spremenil ta paradigm. Kot modularna zasnova Mednarodne vesoljske postaje, kjer lahko astronavti zamenjajo posamezne komponente brez ponovne gradnje celotne strukture, nam AJAX omogoča posodabljanje določenih delov spletne strani brez ponovnega nalaganja vsega. Čeprav ime omenja XML, danes večinoma uporabljamo JSON, vendar osnovno načelo ostaja: posodobi samo tisto, kar je treba spremeniti. ```mermaid sequenceDiagram participant User participant Browser participant JavaScript participant Server User->>Browser: Interacts with page Browser->>JavaScript: Triggers event handler JavaScript->>Server: Fetches only needed data Server->>JavaScript: Returns JSON data JavaScript->>Browser: Updates specific page elements Browser->>User: Shows updated content (no reload) ``` ![Delovni tok posodobitev v enostranski aplikaciji](../../../../translated_images/spa.268ec73b41f992c2a21ef9294235c6ae597b3c37e2c03f0494c2d8857325cc57.sl.png) **Zakaj se SPA zdi veliko boljša:** - Posodobijo se samo deli, ki so se dejansko spremenili (pametno, kajne?) - Ni več motečih prekinitev - vaši uporabniki ostanejo v toku - Manj podatkov potuje po omrežju, kar pomeni hitrejše nalaganje - Vse se zdi hitro in odzivno, kot aplikacije na vašem telefonu ### Evolucija do sodobnega Fetch API Sodobni brskalniki zagotavljajo [`Fetch` API](https://developer.mozilla.org/docs/Web/API/Fetch_API), ki nadomešča starejši [`XMLHttpRequest`](https://developer.mozilla.org/docs/Web/API/XMLHttpRequest/Using_XMLHttpRequest). Kot razlika med upravljanjem telegrafa in uporabo e-pošte, Fetch API uporablja obljube za čistejšo asinhrono kodo in naravno obravnava JSON. | Funkcija | XMLHttpRequest | Fetch API | |----------|----------------|-----------| | **Sintaksa** | Zapletena, temelji na povratnih klicih | Čista, temelji na obljubah | | **Obravnava JSON** | Zahteva ročno obdelavo | Vgrajena metoda `.json()` | | **Obravnava napak** | Omejene informacije o napakah | Celovite podrobnosti o napakah | | **Sodobna podpora** | Združljivost z dediščino | ES6+ obljube in async/await | > 💡 **Združljivost brskalnikov**: Dobra novica - Fetch API deluje v vseh sodobnih brskalnikih! Če vas zanimajo specifične različice, [caniuse.com](https://caniuse.com/fetch) ima celotno zgodbo o združljivosti. > **Zaključek:** - Odlično deluje v Chrome, Firefox, Safari in Edge (praktično povsod, kjer so vaši uporabniki) - Samo Internet Explorer potrebuje dodatno pomoč (in iskreno, čas je, da se poslovimo od IE) - Popolnoma vas pripravi na elegantne vzorce async/await, ki jih bomo uporabili kasneje ### Implementacija prijave uporabnika in pridobivanja podatkov Zdaj bomo implementirali sistem prijave, ki bo vašo bančno aplikacijo spremenil iz statičnega prikaza v funkcionalno aplikacijo. Kot avtentikacijski protokoli, ki se uporabljajo v varnih vojaških objektih, bomo preverili uporabniške podatke in nato omogočili dostop do njihovih specifičnih podatkov. Gradili bomo postopoma, začenši z osnovno avtentikacijo in nato dodali zmožnosti pridobivanja podatkov. #### Korak 1: Ustvarite osnovo funkcije za prijavo Odprite datoteko `app.js` in dodajte novo funkcijo `login`. Ta bo obravnavala proces avtentikacije uporabnika: ```javascript async function login() { const loginForm = document.getElementById('loginForm'); const user = loginForm.user.value; } ``` **Razčlenimo to:** - Ključna beseda `async` pove JavaScriptu "hej, ta funkcija bo morda morala počakati na nekatere stvari" - Iz strani pridobimo naš obrazec (nič posebnega, samo najdemo ga po ID-ju) - Nato izvlečemo, kar je uporabnik vnesel kot svoje uporabniško ime - Tukaj je zanimiv trik: do katerega koli vnosa obrazca lahko dostopate prek atributa `name` - ni potrebe po dodatnih klicih getElementById! > 💡 **Vzorec dostopa do obrazca**: Vsak kontrolnik obrazca je dostopen prek njegovega imena (nastavljenega v HTML-ju z atributom `name`) kot lastnost elementa obrazca. To zagotavlja čist, berljiv način za pridobivanje podatkov obrazca. #### Korak 2: Ustvarite funkcijo za pridobivanje podatkov o računu Nato bomo ustvarili namensko funkcijo za pridobivanje podatkov o računu s strežnika. To sledi istemu vzorcu kot vaša funkcija za registracijo, vendar se osredotoča na pridobivanje podatkov: ```javascript async function getAccount(user) { try { const response = await fetch('//localhost:5000/api/accounts/' + encodeURIComponent(user)); return await response.json(); } catch (error) { return { error: error.message || 'Unknown error' }; } } ``` **Kaj ta koda doseže:** - **Uporablja** sodobni `fetch` API za asinhrono zahtevanje podatkov - **Sestavi** URL zahteve GET s parametrom uporabniškega imena - **Uporabi** `encodeURIComponent()` za varno obravnavo posebnih znakov v URL-jih - **Pretvori** odgovor v JSON format za enostavno manipulacijo podatkov - **Obravnava** napake na eleganten način, tako da vrne objekt napake namesto da se sesuje > ⚠️ **Opomba o varnosti**: Funkcija `encodeURIComponent()` obravnava posebne znake v URL-jih. Kot kodirni sistemi, ki se uporabljajo v pomorskih komunikacijah, zagotavlja, da vaše sporočilo prispe točno tako, kot je bilo mišljeno, in preprečuje, da bi znaki, kot sta "#" ali "&", bili napačno interpretirani. > **Zakaj je to pomembno:** - Preprečuje, da bi posebni znaki pokvarili URL-je - Ščiti pred napadi manipulacije URL-jev - Zagotavlja, da vaš strežnik prejme predvidene podatke - Sledi varnim kodirnim praksam #### Razumevanje HTTP GET zahtevkov Morda vas bo presenetilo: ko uporabite `fetch` brez dodatnih možnosti, samodejno ustvari [`GET`](https://developer.mozilla.org/docs/Web/HTTP/Methods/GET) zahtevo. To je popolno za to, kar počnemo - prosimo strežnik: "hej, lahko vidim podatke o tem uporabnikovem računu?" Pomislite na GET zahteve kot na vljudno prošnjo za izposojo knjige iz knjižnice - zahtevate ogled nečesa, kar že obstaja. POST zahteve (ki smo jih uporabili za registracijo) so bolj podobne oddaji nove knjige, ki jo je treba dodati v zbirko. | GET zahteva | POST zahteva | |-------------|-------------| | **Namen** | Pridobivanje obstoječih podatkov | Pošiljanje novih podatkov na strežnik | | **Parametri** | V poti URL-ja/poizvedbi | V telesu zahteve | | **Predpomnjenje** | Brskalniki lahko predpomnijo | Običajno ni predpomnjeno | | **Varnost** | Vidno v URL-ju/dnevnikih | Skrito v telesu zahteve | #### Korak 3: Povezovanje vsega skupaj Zdaj za zadovoljiv del - povežimo vašo funkcijo za pridobivanje podatkov o računu s procesom prijave. Tukaj se vse sestavi: ```javascript async function login() { const loginForm = document.getElementById('loginForm'); const user = loginForm.user.value; const data = await getAccount(user); if (data.error) { return console.log('loginError', data.error); } account = data; navigate('/dashboard'); } ``` Ta funkcija sledi jasnemu zaporedju: - Izvleče uporabniško ime iz vnosa obrazca - Zahteva podatke o uporabnikovem računu s strežnika - Obravnava morebitne napake, ki se pojavijo med procesom - Shrani podatke o računu in se ob uspehu premakne na nadzorno ploščo > 🎯 **Vzorec Async/Await**: Ker je `getAccount` asinhrona funkcija, uporabimo ključno besedo `await`, da zaustavimo izvajanje, dokler strežnik ne odgovori. To preprečuje, da bi koda nadaljevala z nedoločenimi podatki. #### Korak 4: Ustvarjanje prostora za vaše podatke Vaša aplikacija potrebuje nekje, kjer si zapomni podatke o računu, ko so naloženi. Pomislite na to kot na kratkoročni spomin vaše aplikacije - prostor za shranjevanje trenutnih uporabniških podatkov. Dodajte to vrstico na vrh vaše datoteke `app.js`: ```javascript // This holds the current user's account data let account = null; ``` **Zakaj to potrebujemo:** - Ohranja podatke o računu dostopne od kjerkoli v vaši aplikaciji - Začetek z `null` pomeni "še nihče ni prijavljen" - Posodobi se, ko se nekdo uspešno prijavi ali registrira - Deluje kot enoten vir resnice - brez zmede glede tega, kdo je prijavljen #### Korak 5: Povežite svoj obrazec Zdaj povežimo vašo novo funkcijo za prijavo z vašim HTML obrazcem. Posodobite oznako obrazca tako: ```html
``` **Kaj ta majhna sprememba naredi:** - Ustavi obrazec, da ne opravi svojega privzetega "ponovno naloži celotno stran" vedenja - Namesto tega pokliče vašo prilagojeno JavaScript funkcijo - Ohranja vse gladko in v slogu enostranske aplikacije - Omogoča vam popoln nadzor nad tem, kaj se zgodi, ko uporabniki pritisnejo "Prijava" #### Korak 6: Izboljšajte svojo funkcijo za registracijo Za doslednost posodobite svojo funkcijo `register`, da tudi shrani podatke o računu in se premakne na nadzorno ploščo: ```javascript // Add these lines at the end of your register function account = result; navigate('/dashboard'); ``` **Ta izboljšava zagotavlja:** - **Nemoten** prehod od registracije do nadzorne plošče - **Dosledno** uporabniško izkušnjo med prijavo in registracijo - **Takojšnji** dostop do podatkov o računu po uspešni registraciji #### Testiranje vaše implementacije ```mermaid flowchart TD A[User enters credentials] --> B[Login function called] B --> C[Fetch account data from server] C --> D{Data received successfully?} D -->|Yes| E[Store account data globally] D -->|No| F[Display error message] E --> G[Navigate to dashboard] F --> H[User stays on login page] ``` **Čas je, da jo preizkusite:** 1. Ustvarite nov račun, da se prepričate, da vse deluje 2. Poskusite se prijaviti s temi istimi podatki 3. Pokukajte v konzolo brskalnika (F12), če se kaj zdi narobe 4. Prepričajte se, da pristane na nadzorni plošči po uspešni prijavi Če kaj ne deluje, ne paničarite! Večina težav so preproste napake, kot so tipkarske napake ali pozabljanje zagnati API strežnik. #### Kratek beseda o čarovniji med različnimi izvoroma Morda se sprašujete: "Kako moja spletna aplikacija komunicira s tem API strežnikom, ko tečejo na različnih vratih?" Odlično vprašanje! To se dotika nečesa, na kar naleti vsak spletni razvijalec. > 🔒 **Varnost med različnimi izvoroma**: Brskalniki uveljavljajo "politiko istega izvora", da preprečijo nepooblaščeno komunikacijo med različnimi domenami. Kot sistem kontrolnih točk v Pentagonu preverjajo, ali je komunikacija pooblaščena, preden dovolijo prenos podatkov. > **V naši nastavitvi:** - Vaša spletna aplikacija teče na `localhost:3000` (razvojni strežnik) - Vaš API strežnik teče na `localhost:5000` (strežnik zaledja) - API strežnik vključuje [CORS glave](https://developer.mozilla.org/docs/Web/HTTP/CORS), ki izrecno dovoljujejo komunikacijo z vašo spletno aplikacijo Ta konfiguracija odraža razvoj v resničnem svetu, kjer aplikacije na sprednjem in zadnjem delu običajno tečejo na ločenih strežnikih. > 📚 **Več o tem**: Poglobite se v API-je in pridobivanje podatkov s tem obsežnim [Microsoft Learn modulom o API-jih](https://docs.microsoft.com/learn/modules/use-apis-discover-museum-art/?WT.mc_id=academic-77807-sagibbon). ## Prikaz vaših podatkov v HTML Zdaj bomo pridobljene podatke prikazali uporabnikom prek manipulacije DOM-a. Kot proces razvijanja fotografij v temnici, bomo nevidne podatke pretvorili v nekaj, kar lahko uporabniki vidijo in z njimi interagirajo. Manipulacija DOM-a je tehnika, ki statične spletne strani spremeni v dinamične aplikacije, ki posodabljajo svojo vsebino glede na interakcije uporabnikov in odgovore strežnika. ### Izbira pravega orodja za nalogo Ko gre za posodabljanje vašega HTML-ja z JavaScriptom, imate na voljo več možnosti. Pomislite na te kot na različna orodja v orodjarni - vsako je popolno za specifične naloge: | Metoda | Za kaj je odlična | Kdaj jo uporabiti | Stopnja varnosti | |--------|-------------------|-------------------|------------------| | `textContent` | Prikazovanje uporabniških podatkov varno | Kadarkoli prikazujete besedilo | ✅ Zelo varno | | `createElement()` + `append()` | Gradnja kompleksnih postavitev | Ustvarjanje novih sekcij/seznamov | ✅ Zelo varno | | `innerHTML` | Nastavljanje HTML vsebine | ⚠️ Poskusite se temu izogniti | ❌ Tvegano | #### Varni način prikaza besedila: textContent Lastnost [`textContent`](https://developer.mozilla.org/docs/Web/API/Node/textContent) je vaš najboljši prijatelj pri prikazovanju uporabniških podatkov. Je Za bolj kompleksne vsebine združite [`document.createElement()`](https://developer.mozilla.org/docs/Web/API/Document/createElement) z metodo [`append()`](https://developer.mozilla.org/docs/Web/API/ParentNode/append): ```javascript // Safe way to create new elements const transactionItem = document.createElement('div'); transactionItem.className = 'transaction-item'; transactionItem.textContent = `${transaction.date}: ${transaction.description}`; container.append(transactionItem); ``` **Razumevanje tega pristopa:** - **Ustvarja** nove DOM elemente programsko - **Omogoča** popoln nadzor nad atributi in vsebino elementov - **Dovoljuje** kompleksne, ugnezdene strukture elementov - **Ohranja** varnost z ločevanjem strukture od vsebine > ⚠️ **Varnostni vidik**: Čeprav se [`innerHTML`](https://developer.mozilla.org/docs/Web/API/Element/innerHTML) pogosto pojavlja v številnih vadnicah, lahko izvaja vgrajene skripte. Tako kot varnostni protokoli v CERN-u preprečujejo nepooblaščeno izvajanje kode, uporaba `textContent` in `createElement` zagotavlja varnejše alternative. > **Tveganja pri uporabi innerHTML:** - Izvaja vse `