# Sukurkite bankinę programėlę 3 dalis: Duomenų gavimo ir naudojimo metodai Pagalvokite apie „Enterprise“ kompiuterį „Star Trek“ – kai Kapitonas Pikardas klausia apie laivo būseną, informacija atsiranda akimirksniu, neperkraunant visos sąsajos ir jos neperkuriant iš naujo. Toks sklandus informacijos srautas yra būtent tai, ką čia kuriame su dinamišku duomenų gavimu. Šiuo metu jūsų bankinė programėlė yra kaip atspausdintas laikraštis – informatyvi, bet statiška. Mes ją paversime kažkuo panašiu į NASA misijų valdymo centrą, kur duomenys teka nuolat ir atnaujinami realiu laiku, netrukdant naudotojo darbo eigai. Išmoksite, kaip asinchroniškai bendrauti su serveriais, tvarkyti duomenis, kurie atkeliauja skirtingu metu, ir transformuoti žaliąją informaciją į prasmingą turinį savo vartotojams. Tai yra skirtumas tarp demonstracinės ir produkcinės programinės įrangos. ## ⚡ Ką galite padaryti per artimiausias 5 minutes **Greitas startas užimtiems programuotojams** ```mermaid flowchart LR A[⚡ 5 minutės] --> B[Nustatyti API serverį] B --> C[Išbandyti užklausą su curl] C --> D[Sukurti prisijungimo funkciją] D --> E[Pamatyti duomenis veikiant] ``` - **1-2 minutės**: Paleiskite savo API serverį (`cd api && npm start`) ir patikrinkite ryšį - **3 minutė**: Sukurkite paprastą `getAccount()` funkciją naudodami fetch - **4 minutė**: Susiekite prisijungimo formą su `action="javascript:login()"` - **5 minutė**: Išbandykite prisijungimą ir stebėkite, kaip paskyros duomenys atsiranda konsolėje **Greiti testavimo komandų pavyzdžiai**: ```bash # Patvirtinti, kad API veikia curl http://localhost:5000/api # Išbandyti paskyros duomenų gavimą curl http://localhost:5000/api/accounts/test ``` **Kodėl tai svarbu**: Per 5 minutes pamatysite asinchroninio duomenų gavimo magiją, kuri palaiko kiekvieną šiuolaikinę žiniatinklio programėlę. Tai pagrindas, leidžiantis programėlėms atrodyti jautrioms ir gyvoms. ## 🗺️ Jūsų mokymosi kelionė per duomenimis paremtas žiniatinklio programėles ```mermaid journey title Nuo statinių puslapių iki dinamiškų programų section Evoliucijos supratimas Tradiciniai puslapio perkrovimai: 3: You AJAX/SPA privalumų atradimas: 5: You Fetch API modelių įvaldymas: 7: You section Autentifikacijos kūrimas Prisijungimo funkcijų kūrimas: 4: You Asinchroninių operacijų valdymas: 6: You Vartotojo sesijų tvarkymas: 8: You section Dinaminiai UI atnaujinimai DOM manipuliacijos mokymasis: 5: You Sandorių rodymo kūrimas: 7: You Reaguojančių prietaisų skydelių kūrimas: 9: You section Profesionalių modelių taikymas Šablonais pagrįstas atvaizdavimas: 6: You Klaidų valdymo strategijos: 7: You Veikimo optimizavimas: 8: You ``` **Jūsų kelionės tikslas**: Pamokos pabaigoje suprasite, kaip šiuolaikinės žiniatinklio programėlės dinamiškai gauna, apdoroja ir rodo duomenis, sukurdamos sklandžią naudotojo patirtį, kurios tikimės iš profesionalių programų. ## Priešpaskaitinė viktorina [Priešpaskaitinė viktorina](https://ff-quizzes.netlify.app/web/quiz/45) ### Prieš tai reikalinga Prieš pradėdami žiūrėti duomenų gavimą, įsitikinkite, kad turite šiuos komponentus paruoštus: - **Ankstesnė pamoka**: Baigti [Prisijungimo ir Registracijos Formą](../2-forms/README.md) – mes kursime šį pagrindą toliau - **Vietinis serveris**: Įdiekite [Node.js](https://nodejs.org) ir [paleiskite serverio API](../api/README.md), kad būtų tiekiami paskyros duomenys - **API ryšys**: Patikrinkite savo serverio ryšį su šia komanda: ```bash curl http://localhost:5000/api # Tikėtinas atsakymas: "Bank API v1.0.0" ``` Šis greitas testas užtikrina, kad visi komponentai bendrauja teisingai: - Patikrina, ar Node.js veikia tinkamai jūsų sistemoje - Patvirtina, kad jūsų API serveris yra aktyvus ir atsako - Patikrina, ar jūsų programėlė gali pasiekti serverį (kaip radijo ryšio patikrinimas prieš misiją) ## 🧠 Duomenų valdymo ekosistemos apžvalga ```mermaid mindmap root((Duomenų valdymas)) Authentication Flow Login Process Form Validation Credential Verification Session Management User State Global Account Object Navigation Guards Error Handling API Communication Fetch Patterns GET Requests POST Requests Error Responses Data Formats JSON Processing URL Encoding Response Parsing Dynamic UI Updates DOM Manipulation Safe Text Updates Element Creation Template Cloning User Experience Real-time Updates Error Messages Loading States Security Considerations XSS Prevention textContent Usage Input Sanitization Safe HTML Creation CORS Handling Cross-Origin Requests Header Configuration Development Setup ``` **Pagrindinė taisyklė**: Šiuolaikinės žiniatinklio programėlės yra duomenų koordinavimo sistemos – jos suderina naudotojo sąsajas, serverio API ir naršyklės saugumo modelius, kad sukurtų sklandžią, reaguojančią patirtį. --- ## Duomenų gavimo supratimas šiuolaikinėse žiniatinklio programėlėse Būdas, kaip žiniatinklio programėlės tvarko duomenis, per pastaruosius du dešimtmečius dramatiškai pasikeitė. Supratimas apie šią evoliuciją padės jums įvertinti, kodėl tokios šiuolaikinės technikos kaip AJAX ir Fetch API yra tokios galingos ir kodėl jos tapo būtinos įrankiams žiniatinklio kūrėjams. Pažiūrėkime, kaip tradiciniai tinklalapiai veikė palyginti su dinamiškomis, reaguojančiomis programėlėmis, kurias kuriame šiandien. ### Tradicinės daugiasvetės programėlės (MPA) Pirmosiomis žiniatinklio dienomis kiekvienas paspaudimas buvo kaip kanalų keitimas senajame televizoriuje – ekranas tuštėdavo, o tada lėtai rodydavo naują turinį. Tai buvo ankstyvų žiniatinklio programėlių realybė, kai kiekviena sąveika reikšdavo visos puslapio perkūrimą nuo nulio. ```mermaid sequenceDiagram participant User participant Browser participant Server User->>Browser: Spusteli nuorodą arba pateikia formą Browser->>Server: Prašo naujo HTML puslapio Note over Browser: Puslapis tampa tuščias Server->>Browser: Grąžina pilną HTML puslapį Browser->>User: Rodo naują puslapį (mirksėjimas/perkrovimas) ``` ![Atnaujinimo eiga daugiasvetyje programėlėje](../../../../translated_images/lt/mpa.7f7375a1a2d4aa77.webp) **Kodėl toks metodas atrodė nepatogus:** - Kiekvienas paspaudimas reiškė viso puslapio perkūrimą nuo nulio - Vartotojai pertraukė savo mintis dėl erziančių puslapio užsidegimų (mirksnių) - Jūsų interneto ryšys dirbo permušdamas tą patį antraštės ir poraštės turinį vėl ir vėl - Programėlės jautėsi labiau kaip naršymas per popierinių bylų spintą nei naudojimas programinės įrangos ### Šiuolaikinės vieno puslapio programėlės (SPA) AJAX (asinchroninis JavaScript ir XML) visiškai pakeitė šį požiūrį. Kaip Tarptautinės kosmoso stoties modulinis dizainas, kai astronautai gali pakeisti atskirus komponentus neperrengiant visos struktūros, AJAX leidžia atnaujinti konkrečias tinklalapio dalis neperkraunant visko. Nors pavadinime minimas XML, šiandien daugiausia naudojame JSON, bet pagrindinis principas išlieka: atnaujinti tik tai, kas tikrai pasikeitė. ```mermaid sequenceDiagram participant User participant Browser participant JavaScript participant Server User->>Browser: Sąveikauja su puslapiu Browser->>JavaScript: Suveikia įvykio tvarkyklė JavaScript->>Server: Užkrauna tik reikalingus duomenis Server->>JavaScript: Grąžina JSON duomenis JavaScript->>Browser: Atnaujina konkrečius puslapio elementus Browser->>User: Rodo atnaujintą turinį (nereikia perkrovimo) ``` ![Atnaujinimo eiga vieno puslapio programėlėje](../../../../translated_images/lt/spa.268ec73b41f992c2.webp) **Kodėl SPA atrodo daug geriau:** - Atnaujinamos tik iš tikrųjų pasikeitusios dalys (protinga, tiesa?) - Nebėra staigių pertrūkių – vartotojai lieka savo veikloje - Mažiau duomenų keliauja per tinklą, todėl greičiau įsikrauna - Viskas atrodo greita ir jautri, kaip programėlės jūsų telefone ### Evoliucija į šiuolaikinį Fetch API Šiuolaikinės naršyklės teikia [`Fetch` API](https://developer.mozilla.org/docs/Web/API/Fetch_API), kuris pakeičia senąjį [`XMLHttpRequest`](https://developer.mozilla.org/docs/Web/API/XMLHttpRequest/Using_XMLHttpRequest). Kaip skirtumas tarp telegrapho ir el. pašto naudojimo, Fetch API naudoja pažadus (promises) sklandesniam asinchroniniam kodui ir natūraliai dirba su JSON. | Funkcija | XMLHttpRequest | Fetch API | |---------|----------------|----------| | **Sintaksė** | Sudėtingos atgalinio kvietimo funkcijos | Švari, su pažadais | | **JSON tvarkymas** | Reikia rankinio analizavimo | Įmontuotas `.json()` metodas | | **Klaidų tvarkymas** | Ribota klaidų informacija | Išsami klaidų informacija | | **Šiuolaikinė palaikymas** | Suderinamumas su senomis naršyklėmis | ES6+ pažadai ir async/await | > 💡 **Naršyklių suderinamumas**: Gera žinia – Fetch API veikia visose šiuolaikinėse naršyklėse! Jei domina specifinės versijos, [caniuse.com](https://caniuse.com/fetch) pateikia pilną suderinamumo informaciją. > **Apibendrinant:** - Veikia puikiai Chrome, Firefox, Safari ir Edge (iš esmės visur, kur yra jūsų vartotojai) - Tik Internet Explorer reikia papildomos pagalbos (ir tiesą sakant, jau laikas atsisveikinti su IE) - Puikiai paruošia jus elegantiškiems async/await modeliams, kuriuos naudosime vėliau ### Vartotojo prisijungimo ir duomenų gavimo įgyvendinimas Dabar įgyvendinkime prisijungimo sistemą, kuri pavers jūsų bankinę programėlę iš statiško vaizdo į funkcionalią aplikaciją. Kaip ir saugumo patikros protokolai karinėje įrangoje, mes patikrinsime vartotojo kredencialus ir suteiksime prieigą prie jų specifinių duomenų. Kursime tai palaipsniui, pradedant nuo bazinės autentifikacijos ir vėliau pridėdami duomenų gavimo galimybes. #### 1 žingsnis: Sukurkite Prisijungimo Funkcijos Pagrindą Atidarykite savo `app.js` failą ir pridėkite naują `login` funkciją. Ji tvarkys vartotojo autentifikacijos procesą: ```javascript async function login() { const loginForm = document.getElementById('loginForm'); const user = loginForm.user.value; } ``` **Suskaidykime tai:** - Tas `async` žodis? Jis sako JavaScript „ei, ši funkcija gali laukti tam tikrų dalykų“ - Mes paimame formą iš puslapio (nieko sudėtingo, tiesiog randame pagal ID) - Tuomet ištraukiame tai, ką vartotojas įrašė kaip savo vartotojo vardą - Štai įdomi gudrybė: galite pasiekti bet kurį formos lauką pagal jo `name` atributą – nereikia papildomai naudoti getElementById! > 💡 **Formos pasiekiamumo modelis**: Kiekvieną formos kontrolę galima pasiekti pagal jos vardą (nustatytą HTML `name` atributu) kaip formos elemento savybę. Tai suteikia švarų ir suprantamą būdą gauti formos duomenis. #### 2 žingsnis: Sukurkite Paskyros Duomenų Gavimo Funkciją Toliau sukursime specialią funkciją, kuri gaus paskyros duomenis iš serverio. Tai atitinka tą patį modelį kaip jūsų registracijos funkcija, bet orientuota į duomenų gavimą: ```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' }; } } ``` **Šis kodas atlieka:** - **Naudoja** modernų `fetch` API asinchroniškai gauti duomenis - **Sudaro** GET užklausos URL su vartotojo vardu kaip parametru - **Taiko** `encodeURIComponent()` specialių simbolių saugumui URL - **Paverčia** atsakymą į JSON formatą lengvesniam duomenų tvarkymui - **Tvarko** klaidas mandagiai, gražindamas klaidos objektą, kad negestų programa > ⚠️ **Saugumo pastaba**: Funkcija `encodeURIComponent()` apsaugo URL nuo specialių simbolių klaidingo interpretavimo. Kaip ir jūrų ryšių kodavimo sistemos, ji užtikrina, kad jūsų žinutė atkeliaus tiksliai tokia, kokia turi būti, apsaugant nuo „#“ ar „&“ simbolių klaidų. > **Kodėl tai svarbu:** - Užkerta kelią specialių simbolių įtakai URL struktūrai - Apsaugo nuo URL manipuliacijos atakų - Užtikrina, kad serveris gautų numatytus duomenis - Atitinka saugaus kodo rašymo praktiką #### HTTP GET Užklausų Supratimas Štai kas gali nustebinti: kai naudojate `fetch` be papildomų nustatymų, jis automatiškai sukuria [`GET`](https://developer.mozilla.org/docs/Web/HTTP/Methods/GET) užklausą. Tai puikiai tinka tam, ką darome – klausiame serverio „ei, ar galiu pamatyti šio vartotojo paskyros duomenis?“ Įsivaizduokite GET užklausas kaip mandagų prašymą pasiskolinti knygą bibliotekoje – jūs prašote pamatyti tai, kas jau yra. POST užklausos (kurias panaudojome registracijoje) yra labiau kaip pateikti naują knygą, kad ji būtų įtraukta į kolekciją. | GET Užklausa | POST Užklausa | |-------------|---------------| | **Paskirtis** | Gauti esamus duomenis | Siųsti naujus duomenis serveriui | | **Parametrai** | URL kelio/užklausos eilutėje | Užklausos kūne | | **Kešavimas** | Gali būti naršyklės kešuojama | Paprastai nekešuojama | | **Saugumas** | Matomas URL/žurnaluose | Paslėptas užklausos kūne | ```mermaid sequenceDiagram participant B as Naršyklė participant S as Serveris Note over B,S: GET Užklausa (Duomenų gavimas) B->>S: GET /api/accounts/test S-->>B: 200 OK + Sąskaitos duomenys Note over B,S: POST Užklausa (Duomenų pateikimas) B->>S: POST /api/accounts + Nauji sąskaitos duomenys S-->>B: 201 Sukurta + Patvirtinimas Note over B,S: Klaidų tvarkymas B->>S: GET /api/accounts/nonexistent S-->>B: 404 Nerasta + Klaidos pranešimas ``` #### 3 žingsnis: Sujunkite viską Dabar smagiausia dalis – susiekite paskyros gavimo funkciją su prisijungimo procesu. Čia viskas dera: ```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'); } ``` Ši funkcija turi aiškią seką: - Išformuoja vartotojo vardą iš formos lauko - Užklausia paskyros duomenų iš serverio - Tvarko visas klaidas, kylančias procese - Saugiai saugo paskyros duomenis ir perveda į pagrindinį puslapį, jei viskas gerai > 🎯 **Async/Await modelis**: Kadangi `getAccount` yra asinchroninė funkcija, naudojame `await`, kad kodo vykdymas palauktų serverio atsakymo. Tai apsaugo nuo kodo veikimo su neapibrėžtais duomenimis. #### 4 žingsnis: Sukurkite laikymui vietą savo duomenims Jūsų programėlė turi turėti vietą, kur atsimins paskyros informaciją po jos gavimo. Galvokite apie tai kaip trumpalaikę programėlės atmintį – vietą, kur saugomi dabartinio vartotojo duomenys patogiai. Pridėkite šią eilutę savo `app.js` failo pradžioje: ```javascript // Čia saugomi dabartinio vartotojo paskyros duomenys let account = null; ``` **Kodėl tai reikalinga:** - Leidžia pasiekti paskyros duomenis iš bet kur programėlėje - Pradinis `null` reiškia „dar niekas neprisijungė“ - Atnaujinama sėkmingo prisijungimo ar registracijos metu - Veikia kaip vienintelis tiesos šaltinis – jokio nesusipratimo, kas prisijungęs #### 5 žingsnis: Susiekite formą Dabar susiekime jūsų naują prisijungimo funkciją su HTML forma. Atnaujinkite savo formos tagą taip: ```html
``` **Ką daro šis mažas pakeitimas:** - Sustabdo formos numatytąjį elgesį „perkrauti visą puslapį“ - Iškviečia jūsų pasirinktą JavaScript funkciją - Užtikrina sklandų ir vieno puslapio aplikacijos patyrimą - Suteikia jums pilną kontrolę, kas vyksta paspaudus „Prisijungti“ #### 6 žingsnis: Pagerinkite savo registracijos funkciją Dėl nuoseklumo, atnaujinkite savo `register` funkciją taip, kad ji taip pat saugotų paskyros duomenis ir pereitų į pagrindinį puslapį: ```javascript // Šias eilutes pridėkite savo registracijos funkcijos pabaigoje account = result; navigate('/dashboard'); ``` **Šis patobulinimas suteikia:** - **Sklandų** perėjimą nuo registracijos prie pagrindinio puslapio - **Nuoseklią** naudotojo patirtį tiek prisijungimo, tiek registracijos procesuose - **Momentinę** prieigą prie paskyros duomenų po sėkmingos registracijos #### Testavimo instrukcija ```mermaid flowchart TD A[Vartotojas įveda prisijungimo duomenis] --> B[Kviesiama prisijungimo funkcija] B --> C[Gaunami paskyros duomenys iš serverio] C --> D{Duomenys sėkmingai gauti?} D -->|Taip| E[Paskyros duomenys saugomi globaliai] D -->|Ne| F[Parodoma klaidos žinutė] E --> G[Navigacija į prietaisų skydelį] F --> H[Vartotojas lieka prisijungimo puslapyje] ``` **Laikas išbandyti:** 1. Sukurkite naują paskyrą, kad įsitikintumėte, jog viskas veikia 2. Pabandykite prisijungti su tais pačiais duomenimis 3. Pasižiūrėkite naršyklės konsolę (F12), jei kažkas atrodo negerai 4. Įsitikinkite, kad po sėkmingo prisijungimo atsiduriate pagrindiniame puslapyje Jei kažkas neveikia, nepanikuokite! Dauguma problemų – paprasti klaidų taisymai, kaip rašybos klaidos ar API serverio nepaleidimas. #### Trumpas paaiškinimas apie Kryžmines Origin Magic Galbūt klaustumėte: „Kaip mano žiniatinklio programėlė bendrauja su šiuo API serveriu, jei jie veikia skirtinguose portuose?“ Puikus klausimas! Tai yra tema, su kuria susiduria kiekvienas žiniatinklio kūrėjas. > 🔒 **Kryžminis origin saugumas**: Naršyklės taiko „vienodo kilmės politiką“, kad užkirstų kelią neautorizuotam bendravimui tarp skirtingų domenų. Kaip punktas Pentagone, jos tikrina, ar bendravimas yra leidžiamas prieš perduodant duomenis. > **Mūsų konfigūracija:** - Jūsų žiniatinklio programėlė veikia `localhost:3000` (kūrimo serveris) - Jūsų API serveris veikia `localhost:5000` (backend serveris) - API serveris pridėjo [CORS antraštes](https://developer.mozilla.org/docs/Web/HTTP/CORS), kurios aiškiai leidžia bendravimą iš jūsų žiniatinklio programėlės Ši konfigūracija atspindi realius vystymo scenarijus, kai frontend ir backend programėlės dažnai veikia skirtinguose serveriuose. > 📚 **Sužinokite daugiau**: Gilinkitės į API ir duomenų gavimą su šiuo išsamų [Microsoft Learn moduliu apie API](https://docs.microsoft.com/learn/modules/use-apis-discover-museum-art/?WT.mc_id=academic-77807-sagibbon). ## Duomenų pateikimas HTML kode Dabar padarysime gautus duomenis matomus vartotojams per DOM manipuliavimą. Kaip fotografijų plėtimasis tamsiame kambaryje, mes paimsime nematomus duomenis ir paversime juos į tai, ką vartotojai gali matyti ir su kuo bendrauti. DOM manipuliavimas yra technika, kuri paverčia statinius tinklalapius į dinamiškas programas, kurios atnaujina savo turinį pagal vartotojo sąveikas ir serverio atsakymus. ### Tinkamo įrankio pasirinkimas darbui Kai kalbama apie HTML atnaujinimą naudojant JavaScript, turite keletą pasirinkimų. Galvokite apie juos kaip apie skirtingus įrankius įrankių dėžėje – kiekvienas puikiai tinka tam tikriems darbams: | Metodas | Kam jis puikus | Kada jį naudoti | Saugumo lygis | |--------|-----------------|----------------|--------------| | `textContent` | Vartotojo duomenų saugus rodymas | Bet kada, kai rodote tekstą | ✅ Nuožmus patikimumas | | `createElement()` + `append()` | Sudėtingų maketų kūrimas | Naujiems skirsniams / sąrašams kurti | ✅ Atsparus klaidoms | | `innerHTML` | HTML turinio nustatymas | ⚠️ Stenkitės jo vengti | ❌ Rizikinga praktika | #### Saugus būdas rodyti tekstą: textContent [`textContent`](https://developer.mozilla.org/docs/Web/API/Node/textContent) savybė yra jūsų geriausias draugas rodant vartotojo duomenis. Tai kaip apsauginis sargas jūsų tinklalapiui – niekas pavojingo neprasprūsta: ```javascript // Saugus, patikimas būdas atnaujinti tekstą const balanceElement = document.getElementById('balance'); balanceElement.textContent = account.balance; ``` **textContent privalumai:** - Traktuoja viską kaip paprastą tekstą (neleidžia vykdyti skriptų) - Automatiškai išvalo esamą turinį - Efektyvus paprastiems teksto atnaujinimams - Suteikia integruotą apsaugą nuo žalingo turinio #### Dinaminių HTML elementų kūrimas Sudėtingesniam turiniui derinkite [`document.createElement()`](https://developer.mozilla.org/docs/Web/API/Document/createElement) su [`append()`](https://developer.mozilla.org/docs/Web/API/ParentNode/append) metodu: ```javascript // Saugus būdas kurti naujus elementus const transactionItem = document.createElement('div'); transactionItem.className = 'transaction-item'; transactionItem.textContent = `${transaction.date}: ${transaction.description}`; container.append(transactionItem); ``` **Šio metodo supratimas:** - **Programiškai** sukuria naujus DOM elementus - **Pilnai valdo** elementų atributus ir turinį - **Leidžia** sudėtingas, įdėtas elementų struktūras - **Išlaiko** saugumą atskirdamas struktūrą nuo turinio > ⚠️ **Saugumo pastaba**: Nors [`innerHTML`](https://developer.mozilla.org/docs/Web/API/Element/innerHTML) dažnai minimas pamokose, jis gali vykdyti įterptus skriptus. Kaip CERN saugumo protokolai neleidžia neautorizuotai vykdyti kodo, taip `textContent` ir `createElement` yra saugesni sprendimai. > **innerHTML rizikos:** - Vykdo bet kokius `