# Vytvoření bankovní aplikace část 3: Způsoby načítání a použití dat Přemýšlejte o počítači Enterprise ve Star Treku – když kapitán Picard žádá o stav lodi, informace se objeví okamžitě, aniž by se celé rozhraní vypnulo a znovu sestavovalo. Tento plynulý tok informací je přesně to, co zde s dynamickým načítáním dat budujeme. Vaše bankovní aplikace je nyní jako tištěné noviny – informativní, ale statická. Proměníme ji ve něco spíše jako velitelský sál NASA, kde data proudí neustále a aktualizují se v reálném čase, aniž by přerušovala práci uživatele. Naučíte se, jak komunikovat se servery asynchronně, jak pracovat s daty, která přicházejí v různých časech, a jak převést surové informace na něco smysluplného pro vaše uživatele. To je rozdíl mezi ukázkovým projektem a softwarem připraveným do ostrého provozu. ## ⚡ Co zvládnete za příštích 5 minut **Rychlá cesta pro zaneprázdněné vývojáře** ```mermaid flowchart LR A[⚡ 5 minut] --> B[Nastavit API server] B --> C[Otestovat získávání pomocí curl] C --> D[Vytvořit přihlašovací funkci] D --> E[Vidět data v akci] ``` - **Minuty 1-2**: Spusťte svůj API server (`cd api && npm start`) a otestujte připojení - **Minuta 3**: Vytvořte základní funkci `getAccount()` pomocí fetch - **Minuta 4**: Propojte přihlašovací formulář s `action="javascript:login()"` - **Minuta 5**: Otestujte přihlášení a sledujte, jak se data účtu objeví v konzoli **Rychlé testovací příkazy**: ```bash # Ověřit, že API běží curl http://localhost:5000/api # Test načítání dat účtu curl http://localhost:5000/api/accounts/test ``` **Proč je to důležité**: Za 5 minut uvidíte kouzlo asynchronního načítání dat, které pohání každou moderní webovou aplikaci. Je to základ, díky kterému aplikace působí rychle a živě. ## 🗺️ Vaše cesta učením se webovým aplikacím řízeným daty ```mermaid journey title Od statických stránek k dynamickým aplikacím section Porozumění evoluci Tradiční obnovování stránek: 3: You Objevte výhody AJAX/SPA: 5: You Osvojte si vzory Fetch API: 7: You section Budování autentizace Vytvořte funkce přihlášení: 4: You Zpracovávejte asynchronní operace: 6: You Spravujte uživatelské relace: 8: You section Dynamické aktualizace UI Naučte se manipulaci s DOM: 5: You Vytvářejte zobrazení transakcí: 7: You Vytvořte responzivní dashboardy: 9: You section Profesionální vzory Šablonové vykreslování: 6: You Strategie zpracování chyb: 7: You Optimalizace výkonu: 8: You ``` **Cíl vaší cesty**: Na konci této lekce pochopíte, jak moderní webové aplikace dynamicky načítají, zpracovávají a zobrazují data, čímž vytvářejí bezproblémové uživatelské zážitky, které očekáváme od profesionálních aplikací. ## Přednáškový kvíz [Pre-lecture quiz](https://ff-quizzes.netlify.app/web/quiz/45) ### Požadavky Než se pustíte do načítání dat, ujistěte se, že máte připravené tyto komponenty: - **Předchozí lekce**: Dokončete [Formulář přihlášení a registrace](../2-forms/README.md) – na tomto základu budeme stavět - **Lokální server**: Nainstalujte [Node.js](https://nodejs.org) a [spusťte API server](../api/README.md) pro poskytování dat o účtech - **Připojení k API**: Otestujte spojení se serverem tímto příkazem: ```bash curl http://localhost:5000/api # Očekávaná odpověď: "Bank API v1.0.0" ``` Tento rychlý test zajistí správnou komunikaci všech komponent: - Ověřuje, že Node.js běží správně na vašem systému - Potvrzuje, že API server je aktivní a reaguje - Validuje, že vaše aplikace může dosáhnout server (jako kontrola rádiového kontaktu před misí) ## 🧠 Přehled ekosystému správy dat ```mermaid mindmap root((Správa dat)) Authentication Flow Login Process Ověření formuláře Ověření přihlašovacích údajů Správa relace User State Globální objekt účtu Ochrana navigace Zpracování chyb API Communication Fetch Patterns Požadavky GET Požadavky POST Chybové odpovědi Data Formats Zpracování JSON Kódování URL Parsování odpovědi Dynamic UI Updates DOM Manipulation Bezpečné aktualizace textu Vytváření elementů Klonování šablon User Experience Aktualizace v reálném čase Chybová hlášení Stav načítání Security Considerations XSS Prevention Použití textContent Sanitizace vstupu Bezpečné vytváření HTML CORS Handling Požadavky mezi doménami Nastavení hlaviček Vývojové nastavení ``` **Základní princip**: Moderní webové aplikace jsou orchestrace dat – koordinují mezi uživatelským rozhraním, serverovými API a bezpečnostními modely prohlížeče, aby vytvořily plynulé a responzivní zážitky. --- ## Pochopení načítání dat v moderních webových aplikacích Způsob, jakým webové aplikace zacházejí s daty, se za poslední dvě desetiletí dramaticky vyvinul. Pochopení této evoluce vám pomůže ocenit, proč jsou moderní techniky jako AJAX a Fetch API tak silné a proč se staly nezbytnými nástroji webových vývojářů. Pojďme se podívat, jak fungovaly tradiční webové stránky ve srovnání s dynamickými, responzivními aplikacemi, které dnes vytváříme. ### Tradiční vícestránkové aplikace (MPA) V počátcích webu byl každý klik jako přepínání kanálů na staré televizi – obrazovka zhasla a pak se pomalu zobrazil nový obsah. Takto fungovaly dřívější webové aplikace, kde každá interakce znamenala znovu vytvoření celé stránky od začátku. ```mermaid sequenceDiagram participant User participant Browser participant Server User->>Browser: Klikne na odkaz nebo odešle formulář Browser->>Server: Žádá o novou HTML stránku Note over Browser: Stránka zůstane prázdná Server->>Browser: Vrací kompletní HTML stránku Browser->>User: Zobrazuje novou stránku (bliknutí/obnovení) ``` ![Update workflow in a multi-page application](../../../../translated_images/cs/mpa.7f7375a1a2d4aa77.webp) **Proč tento přístup působil neohrabaně:** - Každé kliknutí znamenalo znovu vytvořit celou stránku od základů - Uživatelé byli přerušováni uprostřed myšlenky nepříjemným blikáním stránky - Internetové připojení přetěžovalo stahování stejné hlavičky a patičky znovu a znovu - Aplikace působily spíše jako proklikávání složkami spíše než používání softwaru ### Moderní jednosrtnové aplikace (SPA) AJAX (Asynchronous JavaScript and XML) tento paradigmat změnil zcela. Jako modulární design Mezinárodní vesmírné stanice, kde astronauti mohou měnit jednotlivé části bez budování celé struktury znovu, AJAX nám umožňuje aktualizovat konkrétní části webové stránky bez nutnosti načítat vše znovu. Přestože název zmiňuje XML, dnes převážně používáme JSON, ale základní princip zůstává: aktualizovat jen to, co se změnilo. ```mermaid sequenceDiagram participant User participant Browser participant JavaScript participant Server User->>Browser: Interaguje s stránkou Browser->>JavaScript: Spouští obsluhu události JavaScript->>Server: Načte pouze potřebná data Server->>JavaScript: Vrací data v JSONu JavaScript->>Browser: Aktualizuje specifické prvky stránky Browser->>User: Zobrazuje aktualizovaný obsah (bez načítání) ``` ![Update workflow in a single-page application](../../../../translated_images/cs/spa.268ec73b41f992c2.webp) **Proč se SPA cítí mnohem lépe:** - Aktualizují se jen skutečně změněné části (chytře, že?) - Žádné náhlé přerušení – uživatelé zůstávají ve svém toku práce - Méně dat přes síť znamená rychlejší načítání - Všechno je svižné a responzivní, jako aplikace na vašem telefonu ### Vývoj k modernímu Fetch API Moderní prohlížeče nabízejí [`Fetch` API](https://developer.mozilla.org/docs/Web/API/Fetch_API), které nahrazuje starší [`XMLHttpRequest`](https://developer.mozilla.org/docs/Web/API/XMLHttpRequest/Using_XMLHttpRequest). Jako rozdíl mezi obsluhou telegrafu a používáním e-mailu, Fetch API využívá sliby pro čistší asynchronní kód a přirozeně pracuje s JSON. | Vlastnost | XMLHttpRequest | Fetch API | |-----------|----------------|----------| | **Syntaxe** | Složitá na základě callbacků | Čistá založená na Promise | | **Zpracování JSON** | Vyžaduje manuální parsování | Vestavěná metoda `.json()` | | **Zpracování chyb** | Omezené informace o chybách | Detailní informace o chybách | | **Podpora moderních funkcí** | Zpětná kompatibilita | ES6+ Promise a async/await | > 💡 **Kompatibilita prohlížečů**: Dobrá zpráva – Fetch API funguje ve všech moderních prohlížečích! Pokud vás zajímají konkrétní verze, [caniuse.com](https://caniuse.com/fetch) nabízí kompletní přehled kompatibility. > **Shrnutí:** - Funguje skvěle v Chrome, Firefox, Safari a Edge (prakticky všude, kde jsou vaši uživatelé) - Pouze Internet Explorer potřebuje dodatečnou podporu (a upřímně, je čas IE opustit) - Připravuje vás perfektně na elegantní vzory async/await, které budeme později používat ### Implementace přihlášení uživatele a načítání dat Pojďme nyní implementovat přihlašovací systém, který přemění vaši bankovní aplikaci ze statického zobrazení na funkční aplikaci. Jako autentizační protokoly používané v zabezpečených vojenských zařízeních, ověříme uživatelské údaje a poskytneme přístup k jejich specifickým datům. Budeme to tvořit postupně, začneme základní autentizací a poté přidáme schopnosti načítání dat. #### Krok 1: Vytvoření základu funkce přihlášení Otevřete soubor `app.js` a přidejte novou funkci `login`. Ta bude řešit proces autentizace uživatele: ```javascript async function login() { const loginForm = document.getElementById('loginForm'); const user = loginForm.user.value; } ``` **Podrobnosti:** - Klíčové slovo `async` říká JavaScriptu „hele, tahle funkce možná bude muset počkat“ - Načítáme formulář ze stránky (nic složitého, prostě ho najdeme podle ID) - Pak vytáhneme, co uživatel zadal jako své uživatelské jméno - Tip: k hodnotám formuláře se dá přistupovat podle atributu `name` – není třeba dalších getElementById! > 💡 **Přístup k formuláři**: Každý ovládací prvek formuláře lze získat podle jeho jména (nastaveno v HTML pomocí atributu `name`) jako vlastnost formulářového elementu. Je to čistý a přehledný způsob, jak získat data z formuláře. #### Krok 2: Vytvoření funkce pro načítání dat účtu Dále vytvoříme samostatnou funkci pro získání dat o účtu ze serveru. Následuje stejný vzor jako u registrační funkce, ale s důrazem na načítání dat: ```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' }; } } ``` **Co tento kód dělá:** - **Používá** moderní API `fetch` pro asynchronní požadavky - **Sestavuje** GET požadavek s parametrem uživatelského jména v URL - **Používá** `encodeURIComponent()` k bezpečnému zpracování speciálních znaků v URL - **Převede** odpověď do JSON formátu pro snadnou práci s daty - **Řeší** chyby elegantně vrácením chybového objektu místo pádu aplikace > ⚠️ **Bezpečnostní poznámka**: Funkce `encodeURIComponent()` zajišťuje, že speciální znaky v URL (např. "#", "&") nebudou nesprávně zpracovány. Podobně jako kódovací systémy v námořní komunikaci, které zaručují, že zpráva dorazí přesně tak, jak má. > **Proč je to důležité:** - Zabraňuje poškození URL speciálními znaky - Chrání před útoky na manipulaci s URL - Zajišťuje, že server přebírá přesně požadovaná data - Dodržuje bezpečné programovací postupy #### Pochopení HTTP GET požadavků Možná vás překvapí, že když použijete `fetch` bez dalších nastavení, automaticky se provede [`GET`](https://developer.mozilla.org/docs/Web/HTTP/Methods/GET) požadavek. To je ideální pro situace, kdy žádáme server třeba o zobrazení uživatelských dat. GET požadavky jsou jako zdvořilé půjčení si knihy z knihovny – chcete vidět něco, co už existuje. POST požadavky (které jsme používali při registraci) jsou spíše jako přidání nové knihy do sbírky. | GET požadavek | POST požadavek | |--------------|---------------| | **Účel** | Získat existující data | Odeslat nová data na server | | **Parametry** | V URL cestě/parametrech | V těle požadavku | | **Cacheování** | Lze cachovat prohlížečem | Obvykle se necachuje | | **Bezpečnost** | Viditelné v URL/logu | Skryté v těle požadavku | ```mermaid sequenceDiagram participant B as Prohlížeč participant S as Server Note over B,S: GET požadavek (Získávání dat) B->>S: GET /api/accounts/test S-->>B: 200 OK + Data účtu Note over B,S: POST požadavek (Odeslání dat) B->>S: POST /api/accounts + Nová data účtu S-->>B: 201 Vytvořeno + Potvrzení Note over B,S: Zpracování chyb B->>S: GET /api/accounts/nonexistent S-->>B: 404 Nenalezeno + Chybová zpráva ``` #### Krok 3: Sjednocení všeho dohromady Nyní přichází ten uspokojivý okamžik – propojíme funkci pro načtení bankovního účtu s procesem přihlášení. Tady všechno zapadá na své místo: ```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'); } ``` Tato funkce postupuje jasně: - Vytáhne uživatelské jméno z formuláře - Požádá server o data účtu tohoto uživatele - Zpracuje případné chyby v průběhu - Uloží data účtu a přejde na dashboard při úspěchu > 🎯 **Vzorec Async/Await**: Protože `getAccount` je asynchronní funkce, používáme klíčové slovo `await`, které zastaví provádění, dokud server neodpoví. Tím zabráníme pokračování s nedefinovanými daty. #### Krok 4: Vytvoření místa pro data Aplikace potřebuje místo, kde bude uchovávat informace o účtu po načtení. Jako krátkodobou paměť – místo, kde bude mít aktuální uživatel svá data okamžitě po ruce. Přidejte tuto řádku na začátek souboru `app.js`: ```javascript // Toto obsahuje data účtu aktuálního uživatele let account = null; ``` **Proč to potřebujeme:** - Data o účtu jsou přístupná odkudkoliv v aplikaci - Začínáme s `null`, což znamená „zatím nikdo není přihlášen“ - Aktualizuje se po úspěšném přihlášení nebo registraci - Funguje jako jediný zdroj pravdy – žádné nejasnosti, kdo je přihlášen #### Krok 5: Propojte formulář Pojďme nyní připojit vaši novou funkci přihlášení k HTML formuláři. Aktualizujte tag formuláře takto: ```html
``` **Co tahle změna dělá:** - Zabraňuje formuláři, aby provedl výchozí „přenačtení celé stránky“ - Volá vaši vlastní JavaScript funkci místo toho - Udržuje vše plynulé a ve stylu single-page aplikace - Dává vám plnou kontrolu nad tím, co se stane po kliknutí na „Login“ #### Krok 6: Vylepšení registrační funkce Pro konzistenci upravte i funkci `register`, aby také ukládala data účtu a přecházela na dashboard: ```javascript // Přidejte tyto řádky na konec vaší funkce register account = result; navigate('/dashboard'); ``` **Toto vylepšení přináší:** - **Plynulý** přechod z registrace na dashboard - **Konzistentní** uživatelský zážitek mezi přihlášením a registrací - **Okamžitý** přístup k datům účtu po úspěšné registraci #### Testování implementace ```mermaid flowchart TD A[Uživatel zadá přihlašovací údaje] --> B[Funkce přihlášení volána] B --> C[Načíst data účtu ze serveru] C --> D{Data byla úspěšně přijata?} D -->|Ano| E[Uložit data účtu globálně] D -->|Ne| F[Zobrazit chybovou zprávu] E --> G[Přejít na přehled] F --> H[Uživatel zůstává na přihlašovací stránce] ``` **Čas to otestovat:** 1. Vytvořte nový účet a ověřte, že vše funguje 2. Přihlašte se pomocí těchto údajů 3. Pohlédněte do konzole prohlížeče (F12), pokud něco nefunguje podle očekávání 4. Ověřte, že po úspěšném přihlášení jste přesměrováni na dashboard Pokud něco nefunguje, nezoufejte! Většina problémů je jednoduchý překlep nebo zapomenuté spuštění API serveru. #### Krátce o magii Cross-Origin Možná si říkáte: „Jak to moje webová aplikace komunikuje s API serverem, když běží na různých portech?“ Skvělá otázka! To je téma, na které každý webový vývojář dříve či později narazí. > 🔒 **Cross-Origin bezpečnost**: Prohlížeče uplatňují politiku „stejného původu“ (same-origin policy), aby zabránily neautorizované komunikaci mezi různými doménami. Podobně jako kontrolní systém v Pentagónu, ověřují, že komunikace je povolená, než umožní přenos dat. > **V našem prostředí:** - Webová aplikace běží na `localhost:3000` (vývojový server) - API server běží na `localhost:5000` (backend server) - API server obsahuje [CORS hlavičky](https://developer.mozilla.org/docs/Web/HTTP/CORS), které explicitně povolují komunikaci z vaší webové aplikace Toto nastavení odráží reálný vývoj, kdy frontend a backend aplikace obvykle běží na samostatných serverech. > 📚 **Více informací**: Ponořte se hlouběji do API a načítání dat s tímto komplexním [Microsoft Learn modulem o API](https://docs.microsoft.com/learn/modules/use-apis-discover-museum-art/?WT.mc_id=academic-77807-sagibbon). ## Oživení dat v HTML Nyní zpřístupníme načtená data uživatelům pomocí manipulace s DOM. Jako proces vyvolávání fotografií v temné komoře, bereme neviditelná data a zobrazujeme je tak, aby je uživatelé mohli vidět a s nimi interagovat. Manipulace s DOM je technika, která proměňuje statické webové stránky na dynamické aplikace aktualizující svůj obsah na základě interakcí uživatelů a odpovědí serveru. ### Výběr správného nástroje pro práci Při aktualizaci HTML pomocí JavaScriptu máte několik možností. Představte si je jako různé nástroje v krabici s nářadím – každý je ideální pro určitý úkol: | Metoda | Na co je skvělá | Kdy ji použít | Úroveň bezpečnosti | |--------|-----------------|---------------|-------------------| | `textContent` | Bezpečné zobrazování uživatelských dat | Kdykoliv zobrazujete text | ✅ Pevná jistota | | `createElement()` + `append()` | Vytváření komplexních rozvržení | Vytváření nových sekcí/seznamů | ✅ Neprolomitelná | | `innerHTML` | Nastavení HTML obsahu | ⚠️ Raději se této vyhněte | ❌ Riskantní záležitost | #### Bezpečný způsob zobrazení textu: textContent Vlastnost [`textContent`](https://developer.mozilla.org/docs/Web/API/Node/textContent) je váš nejlepší přítel při zobrazování uživatelských dat. Je jako chlapík u vchodu na stránku – nic škodlivého nepustí dovnitř: ```javascript // Bezpečný a spolehlivý způsob aktualizace textu const balanceElement = document.getElementById('balance'); balanceElement.textContent = account.balance; ``` **Výhody textContent:** - Považuje vše za prostý text (zabraňuje spuštění skriptů) - Automaticky vyčistí existující obsah - Efektivní pro jednoduché aktualizace textu - Poskytuje vestavěnou ochranu proti škodlivému obsahu #### Vytváření dynamických HTML prvků Pro složitější obsah kombinujte [`document.createElement()`](https://developer.mozilla.org/docs/Web/API/Document/createElement) s metodou [`append()`](https://developer.mozilla.org/docs/Web/API/ParentNode/append): ```javascript // Bezpečný způsob, jak vytvářet nové prvky const transactionItem = document.createElement('div'); transactionItem.className = 'transaction-item'; transactionItem.textContent = `${transaction.date}: ${transaction.description}`; container.append(transactionItem); ``` **Pochopení tohoto přístupu:** - **Programově** vytváří nové DOM prvky - **Udržuje** plnou kontrolu nad atributy a obsahem prvků - **Umožňuje** složité, vnořené struktury prvků - **Zachovává** bezpečnost oddělením struktury od obsahu > ⚠️ **Bezpečnostní upozornění**: I když se [`innerHTML`](https://developer.mozilla.org/docs/Web/API/Element/innerHTML) objevuje v mnoha návodech, může spouštět vložené skripty. Podobně jako bezpečnostní protokoly na CERNu zabraňují neautorizovanému spuštění kódu, použití `textContent` a `createElement` nabízí bezpečnější alternativy. > **Rizika innerHTML:** - Spouští jakékoliv `