# Изградња апликације за банкарство, део 3: Методе за преузимање и коришћење података Замислите рачунар на Ентерпрајзу из Стар Трека - када капетан Пикард затражи статус брода, информације се појављују тренутно, без гашења целог интерфејса и његовог поновног учитавања. Управо тај беспрекорни ток информација је оно што овде градимо са динамичким преузимањем података. Тренутно, ваша апликација за банкарство је као штампане новине - информативна, али статична. Претворићемо је у нешто налик контролном центру НАСА-е, где подаци континуирано теку и ажурирају се у реалном времену, без прекидања корисничког рада. Научићете како да комуницирате са серверима асинхроно, како да обрађујете податке који стижу у различито време и како да трансформишете сирове информације у нешто значајно за ваше кориснике. Ово је разлика између демонстрације и софтвера спремног за употребу. ## Квиз пре предавања [Квиз пре предавања](https://ff-quizzes.netlify.app/web/quiz/45) ### Предуслови Пре него што се упустите у преузимање података, уверите се да имате следеће компоненте спремне: - **Претходна лекција**: Завршите [Формулар за пријаву и регистрацију](../2-forms/README.md) - наставићемо на основу овога - **Локални сервер**: Инсталирајте [Node.js](https://nodejs.org) и [покрените сервер API](../api/README.md) за пружање података о рачуну - **API конекција**: Тестирајте вашу серверску конекцију овом командом: ```bash curl http://localhost:5000/api # Expected response: "Bank API v1.0.0" ``` Овај брзи тест осигурава да сви делови комуницирају исправно: - Потврђује да Node.js исправно ради на вашем систему - Проверава да ли је ваш API сервер активан и одговара - Верификује да ваша апликација може да се повеже са сервером (као провера радио контакта пре мисије) --- ## Разумевање преузимања података у модерним веб апликацијама Начин на који веб апликације обрађују податке драматично се развио током последње две деценије. Разумевање ове еволуције помоћи ће вам да цените зашто су модерне технике као што су AJAX и Fetch API толико моћне и зашто су постале суштински алати за веб програмере. Хајде да истражимо како су традиционални веб-сајтови функционисали у поређењу са динамичним, одзивним апликацијама које данас градимо. ### Традиционалне апликације са више страница (MPA) У раним данима веба, сваки клик је био као мењање канала на старом телевизору - екран би се угасио, а затим полако пребацио на нови садржај. То је била реалност раних веб апликација, где је свака интеракција значила потпуно поновно учитавање целе странице. ```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) ```  **Зашто је овај приступ био незграпан:** - Сваки клик је значио поновно учитавање целе странице - Корисници су били прекидани у размишљању због тих досадних трептаја странице - Ваша интернет конекција је радила прековремено, преузимајући исти заглавље и подножје изнова и изнова - Апликације су више личиле на прелиставање фиоке него на коришћење софтвера ### Модерне апликације са једном страницом (SPA) AJAX (Асинхрони ЈаваСкрипт и XML) је потпуно променио овај парадигму. Као модуларни дизајн Међународне свемирске станице, где астронаути могу заменити појединачне компоненте без поновног изградње целе структуре, AJAX нам омогућава да ажурирамо одређене делове веб странице без поновног учитавања свега. Иако име помиње XML, данас углавном користимо JSON, али основни принцип остаје исти: ажурирајте само оно што треба да се промени. ```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) ```  **Зашто SPA апликације делују боље:** - Ажурирају се само делови који су се стварно променили (паметно, зар не?) - Нема више неугодних прекида - ваши корисници остају у свом току - Мање података путује мрежом, што значи брже учитавање - Све делује брзо и одзивно, као апликације на вашем телефону ### Еволуција ка модерном Fetch API Модерни претраживачи пружају [`Fetch` API](https://developer.mozilla.org/docs/Web/API/Fetch_API), који замењује старији [`XMLHttpRequest`](https://developer.mozilla.org/docs/Web/API/XMLHttpRequest/Using_XMLHttpRequest). Као разлика између управљања телеграфом и коришћења е-поште, Fetch API користи промисе за чистији асинхрони код и природно обрађује JSON. | Карактеристика | XMLHttpRequest | Fetch API | |----------------|----------------|-----------| | **Синтакса** | Комплексна, заснована на повратним позивима | Чиста, заснована на промисама | | **Обрада JSON-а** | Потребно ручно парсирање | Уграђена метода `.json()` | | **Обрада грешака** | Ограничене информације о грешкама | Детаљне информације о грешкама | | **Модерна подршка** | Компатибилност са старим верзијама | ES6+ промисе и async/await | > 💡 **Компатибилност претраживача**: Добра вест - Fetch API ради у свим модерним претраживачима! Ако сте радознали о специфичним верзијама, [caniuse.com](https://caniuse.com/fetch) има комплетну причу о компатибилности. > **Суштина:** - Одлично ради у Chrome, Firefox, Safari и Edge (у основи свуда где су ваши корисници) - Само Internet Explorer захтева додатну помоћ (и искрено, време је да се опростимо од IE) - Савршено вас припрема за елегантне async/await шаблоне које ћемо касније користити ### Имплементација пријаве корисника и преузимања података Сада ћемо имплементирати систем пријаве који трансформише вашу апликацију за банкарство из статичног приказа у функционалну апликацију. Као протоколи за аутентификацију који се користе у сигурним војним објектима, проверићемо корисничке акредитиве и затим омогућити приступ њиховим специфичним подацима. Градићемо ово постепено, почевши од основне аутентификације, а затим додајући могућности преузимања података. #### Корак 1: Креирање основе функције за пријаву Отворите ваш `app.js` фајл и додајте нову функцију `login`. Ова функција ће обрађивати процес аутентификације корисника: ```javascript async function login() { const loginForm = document.getElementById('loginForm'); const user = loginForm.user.value; } ``` **Разложимо ово:** - Та кључна реч `async`? Она говори ЈаваСкрипту "хеј, ова функција можда треба да сачека неке ствари" - Проналазимо наш формулар на страници (ништа посебно, само га проналазимо по његовом ID-у) - Затим извлачимо оно што је корисник укуцао као своје корисничко име - Ево једног лепог трика: можете приступити било којем уносу формулара преко његовог `name` атрибута - нема потребе за додатним позивима getElementById! > 💡 **Шаблон за приступ формулару**: Сваком контролном елементу формулара може се приступити преко његовог имена (постављеног у HTML-у помоћу атрибута `name`) као својству елемента формулара. Ово пружа чист и читљив начин за добијање података из формулара. #### Корак 2: Креирање функције за преузимање података о рачуну Затим ћемо креирати посебну функцију за преузимање података о рачуну са сервера. Ово следи исти шаблон као ваша функција за регистрацију, али се фокусира на преузимање података: ```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' }; } } ``` **Шта овај код постиже:** - **Користи** модерни `fetch` API за асинхроно захтевање података - **Конструише** URL GET захтева са параметром корисничког имена - **Примењује** `encodeURIComponent()` за сигурно руковање специјалним карактерима у URL-овима - **Претвара** одговор у JSON формат за лаку манипулацију подацима - **Обрађује** грешке на елегантан начин, враћајући објекат грешке уместо да се апликација сруши > ⚠️ **Напомена о безбедности**: Функција `encodeURIComponent()` обрађује специјалне карактере у URL-овима. Као системи кодирања који се користе у поморским комуникацијама, она осигурава да ваша порука стигне тачно онако како је намењена, спречавајући да се карактери попут "#" или "&" погрешно интерпретирају. > **Зашто је ово важно:** - Спречава да специјални карактери прекину URL-ове - Штити од напада манипулације URL-овима - Осигурава да ваш сервер добије намењене податке - Практикује сигурно кодирање #### Разумевање HTTP GET захтева Ево нечега што вас може изненадити: када користите `fetch` без додатних опција, он аутоматски креира [`GET`](https://developer.mozilla.org/docs/Web/HTTP/Methods/GET) захтев. Ово је савршено за оно што радимо - питамо сервер "хеј, могу ли да видим податке о рачуну овог корисника?" Размислите о GET захтевима као о љубазном тражењу позајмљивања књиге из библиотеке - тражите да видите нешто што већ постоји. POST захтеви (које смо користили за регистрацију) су више као подношење нове књиге да се дода у колекцију. | GET захтев | POST захтев | |------------|-------------| | **Сврха** | Преузимање постојећих података | Слање нових података серверу | | **Параметри** | У URL путањи/низу упита | У телу захтева | | **Кеширање** | Може бити кеширано од стране претраживача | Обично није кеширано | | **Безбедност** | Видљиво у URL-у/логовима | Скривено у телу захтева | #### Корак 3: Спајање свега Сада долазимо до задовољавајућег дела - повежимо вашу функцију за преузимање података о рачуну са процесом пријаве. Овде се све уклапа: ```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'); } ``` Ова функција следи јасан низ: - Извлачи корисничко име из уноса формулара - Захтева податке о рачуну корисника са сервера - Обрађује све грешке које се јаве током процеса - Чува податке о рачуну и прелази на контролни панел након успешне пријаве > 🎯 **Шаблон async/await**: Пошто је `getAccount` асинхрона функција, користимо кључну реч `await` да паузирамо извршење док сервер не одговори. Ово спречава да код настави са неодређеним подацима. #### Корак 4: Креирање места за ваше податке Вашој апликацији је потребно место где ће памтити информације о рачуну након што их учита. Размислите о овоме као о краткорочној меморији ваше апликације - месту где се чувају подаци тренутног корисника. Додајте ову линију на врх вашег `app.js` фајла: ```javascript // This holds the current user's account data let account = null; ``` **Зашто нам је ово потребно:** - Чува податке о рачуну доступним са било ког места у вашој апликацији - Почетак са `null` значи "нико још није пријављен" - Ажурира се када се неко успешно пријави или региструје - Делује као један извор истине - нема конфузије око тога ко је пријављен #### Корак 5: Повезивање вашег формулара Сада повежимо вашу нову функцију за пријаву са вашим HTML формуларом. Ажурирајте ваш формулар овако: ```html
``` **Шта ова мала промена ради:** - Спречава формулар да ради своје подразумевано "поново учитај целу страницу" понашање - Позива вашу прилагођену ЈаваСкрипт функцију уместо тога - Одржава све глатко и у стилу апликације са једном страницом - Даје вам потпуну контролу над оним што се дешава када корисници притисну "Пријави се" #### Корак 6: Унапређење функције за регистрацију Ради доследности, ажурирајте вашу функцију `register` тако да такође чува податке о рачуну и прелази на контролни панел: ```javascript // Add these lines at the end of your register function account = result; navigate('/dashboard'); ``` **Ово унапређење пружа:** - **Беспрекорну** транзицију од регистрације до контролне табле - **Доследно** корисничко искуство између процеса пријаве и регистрације - **Тренутни** приступ подацима о рачуну након успешне регистрације #### Тестирање ваше имплементације ```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] ``` **Време је да испробате:** 1. Креирајте нови налог да бисте се уверили да све функционише 2. Покушајте да се пријавите са истим акредитивима 3. Погледајте конзолу вашег претраживача (F12) ако нешто изгледа погрешно 4. Уверите се да сте стигли на контролни панел након успешне пријаве Ако нешто не функционише, не паничите! Већина проблема се лако решава, као што су правописне грешке или заборављање да се покрене API сервер. #### Брза реч о магији прекограничне комуникације Можда се питате: "Како моја веб апликација комуницира са овим API сервером када раде на различитим портовима?" Одлично питање! Ово се односи на нешто са чиме се сваки веб програмер пре или касније сусретне. > 🔒 **Безбедност прекограничне комуникације**: Претраживачи примењују "политику истог порекла" како би спречили неовлашћену комуникацију између различитих домена. Као систем контроле приступа у Пентагону, они проверавају да ли је комуникација овлашћена пре него што дозволе пренос података. > **У нашем подешавању:** - Ваша веб апликација ради на `localhost:3000` (развојни сервер) - Ваш API сервер ради на `localhost Za složeniji sadržaj, kombinujte [`document.createElement()`](https://developer.mozilla.org/docs/Web/API/Document/createElement) sa metodom [`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 ovog pristupa:** - **Kreira** nove DOM elemente programatski - **Omogućava** potpunu kontrolu nad atributima i sadržajem elemenata - **Dozvoljava** složene, ugnježdene strukture elemenata - **Čuva** sigurnost razdvajanjem strukture od sadržaja > ⚠️ **Bezbednosni aspekt**: Iako se [`innerHTML`](https://developer.mozilla.org/docs/Web/API/Element/innerHTML) često pojavljuje u tutorijalima, može izvršavati ugrađene skripte. Kao što bezbednosni protokoli u CERN-u sprečavaju neovlašćeno izvršavanje koda, korišćenje `textContent` i `createElement` pruža sigurnije alternative. > **Rizici korišćenja innerHTML:** - Izvršava sve `