# Креирање Банкарске Апликације Део 3: Методе Преузимања и Коришћења Података Замислите рачунар на Enterprise у Стар Треку - када капетан Пикард пита за статус брода, информације се појављују одмах без потпуног гашења и поновног састављања интерфејса. Тај беспрекорни ток информација је управо оно што овде градимо са динамичним преузимањем података. Тренутно је ваша банкарска апликација као штампане новине - информативна али статична. Претворићемо је у нешто више као контролни центар НАСА-е, где подаци непрекидно тече и ажурирају се у реалном времену без прекида у раду корисника. Научићете како да комуницирате са серверима асинхроно, да руковање подацима који стижу у различито време, и да трансформишете сирове информације у нешто значајно за ваше кориснике. Ово је разлика између демо и софтвера спремног за продукцију. ## ⚡ Шта Можете Урадити У Следећих 5 Минута **Брзи Почетни Водич за Задузете Програмере** ```mermaid flowchart LR A[⚡ 5 минута] --> B[Постави API сервер] B --> C[Тестирај fetch са curl] C --> D[Креирај login функцију] D --> E[Погледај податке у акцији] ``` - **Минута 1-2**: Покрените свој API сервер (`cd api && npm start`) и тестирајте конекцију - **Минута 3**: Направите основну `getAccount()` функцију коришћењем fetch - **Минута 4**: Повежите форму за пријаву са `action="javascript:login()"` - **Минута 5**: Тестирајте пријаву и пратите појаву података о рачуну у конзоли **Команде за Брзо Тестирање**: ```bash # Провери да ли API ради curl http://localhost:5000/api # Тест преузимања података налога curl http://localhost:5000/api/accounts/test ``` **Зашто је ово важно**: За 5 минута видећете магију асинхроног преузимања података која покреће сваку модерну веб апликацију. Ово је основа која апликације чини одзивним и живим. ## 🗺️ Ваш Пут Ученика Кроз Веб Апликације Водене Подацима ```mermaid journey title Од статичних страница до динамичких апликација section Разумевање еволуције Традиционално поново учитавање странице: 3: You Откривање предности AJAX/SPA: 5: You Савладавање узорака Fetch API: 7: You section Изградња аутентификације Креирање функција за пријаву: 4: You Руководење асинхроним операцијама: 6: You Управљање корисничким сесијама: 8: You section Динамичка ажурирања корисничког интерфејса Учење манипулације DOM-ом: 5: You Изградња приказа трансакција: 7: You Креирање одзивних контролних табли: 9: You section Професионални узорци Приказивање засновано на шаблонима: 6: You Стратегије исправке грешака: 7: You Оптимизација перформанси: 8: You ``` **Циљ Вашег Пута**: До краја овог часа разумећете како модерне веб апликације преузимају, обрађују и приказују податке динамично, стварајући беспрекорно корисничко искуство какво очекујемо од професионалних апликација. ## Пред-Квиз [Pre-lecture quiz](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 # Очекивани одговор: "Bank API v1.0.0" ``` Овај брзи тест осигурава да све компоненте исправно комуницирају: - Проверава да ли је Node.js покренут правилно на вашем систему - Потврђује да је ваш API сервер активан и одговара - Валидава да ваша апликација може да достигне сервер (као проверу радио везе пре мисије) ## 🧠 Преглед Екосистема Управљања Подацима ```mermaid mindmap root((Управљање подацима)) 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 ``` **Основно Начело**: Модерне веб апликације су системи оркестрације података – координишу између корисничких интерфејса, серверских API-ја и безбедносних модела прегледача како би створиле беспрекорно, одзивно искуство. --- ## Разумевање Преузимања Података у Модерним Веб Апликацијама Начин на који веб апликације рукују подацима драстично се променио у последње две деценије. Разумевање ове еволуције ће вам помоћи да схватите зашто су модерне технике попут AJAX-а и Fetch API-ја тако моћне и зашто су постале неопходни алати веб програмера. Истражимо како су традиционалне веб странице радиле у односу на динамичне, одзивне апликације које данас правимо. ### Традиционалне Мултистраничне Апликације (MPA) У раним данима веба сваки клик је био као мењање канала на старом телевизору – екран би се искључио, па полако подешавао на нови садржај. То је била реалност раних веб апликација, где је свака интеракција значила потпуно обновљавање целе странице од почетка. ```mermaid sequenceDiagram participant User participant Browser participant Server User->>Browser: Кликне на везу или пошаље формулар Browser->>Server: Затражи нову HTML страницу Note over Browser: Страница постаје празна Server->>Browser: Врати потпуну HTML страницу Browser->>User: Прикаже нову страницу (блиц/преузимање) ```  **Зашто је овај приступ деловао нефлексибилно:** - Сваки клик је значио обнову целе странице од нуле - Корисници су били прекидани у мислима оним досадним трептањем страница - Ваша интернет конекција је радила прековремено преузимајући исти заглавље и подножје изнова и изнова - Апликације су деловале више као кликање кроз фиоку са документацијом него као софтвер ### Модерне Једностраничне Апликације (SPA) AJAX (Асинхрони ЏаваСкрипт и XML) је у потпуности променио ову парадигму. Као модуларни дизајн Међународне свемирске станице, где астронаути могу заменити појединачне компоненте без обнављања целе структуре, AJAX нам омогућава да ажурирамо специфичне делове веб странице без поновног учитавања свега. Упркос имену које помиње XML, данас углавном користимо JSON, али основно начело остаје: ажурирати само оно што треба да се промени. ```mermaid sequenceDiagram participant User participant Browser participant JavaScript participant Server User->>Browser: Интеракција са страницом Browser->>JavaScript: Активира обраду догађаја JavaScript->>Server: Преузима само потребне податке Server->>JavaScript: Враћа JSON податке JavaScript->>Browser: Ажурира одређене елементе странице Browser->>User: Приказује ажуриран садржај (без поновног учитавања) ```  **Зашто 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 | |---------|----------------|----------| | **Синтакса** | Компликован callback базиран | Чист, заснован на промисима | | **Руковање 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` кључна реч? Кажемо JavaScript-у "хеј, ова функција ће можда морати да чека" - Узимамо нашу форму са странице (ништа посебно, само је налазимо по 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 за асинхроне захтеве - **Гради** GET URL упит са параметром корисничког имена - **Примeњује** `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-у/логовима | Сакривено у телу захтева | ```mermaid sequenceDiagram participant B as Прегледач participant S as Сервер Note over B,S: GET Захтев (Примање података) B->>S: GET /api/accounts/test S-->>B: 200 У реду + Подаци налога Note over B,S: POST Захтев (Слање података) B->>S: POST /api/accounts + Нови подаци налога S-->>B: 201 Креирано + Потврда Note over B,S: Обрада грешака B->>S: GET /api/accounts/nonexistent S-->>B: 404 Није пронађено + Порука о грешци ``` #### Корак 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 // Ово чува податке налога текућег корисника let account = null; ``` **Зашто нам ово треба:** - Олакшава приступ подацима о рачуну са било ког места у апликацији - Почетна вредност `null` значи "још нико није пријављен" - Ажурира се када се корисник успешно пријави или региструје - Поноси се као једини извор истине - нема конфузије ко је пријављен #### Корак 5: Повежите Ваша Форми Хајде сада да повежемо вашу сјајну нову функцију пријаве са HTML формом. Ажурирајте ваш `
``` **Шта ова мала измена ради:** - Спречава да форма ради подразумевано "поново учитавање целе странице" - Позива вашу прилагођену JavaScript функцију - Чини све глатким и сличним једностраничним апликацијама - Даје вам потпуну контролу шта се дешава када корисници кликну „Пријави се“ #### Корак 6: Побољшајте Функцију Регистрације За доследност, ажурирајте вашу `register` функцију да такође чува податке о рачуну и пређе на контролну таблу: ```javascript // Додајте ове линије на крају ваше регистрационе функције account = result; navigate('/dashboard'); ``` **Ово побољшање пружа:** - **Беспрекорну** транзицију од регистрације до контролне табле - **Конзистентно** корисничко искуство између пријаве и регистрације - **Одмах** приступ подацима о рачуну након успешне регистрације #### Тестирање Ваше Имплементације ```mermaid flowchart TD A[Корисник уноси акредитиве] --> B[Позива се функција пријаве] B --> C[Преузимају се подаци налога са сервера] C --> D{Да ли су подаци успешно примљени?} D -->|Да| E[Сачувати податке налога глобално] D -->|Не| F[Приказати поруку о грешци] E --> G[Ићи на контролну таблу] F --> H[Корисник остаје на страници за пријаву] ``` **Време је да пробате:** 1. Направите нови налог да проверите да ли све ради 2. Покушајте да се пријавите тим истим акредитивима 3. Погледајте конзолу прегледача (F12) ако нешто делује чудно 4. Уверите се да стижете на контролну таблу након успешне пријаве Ако нешто не ради, не паничите! Већина проблема су једноставне поправке као што су типографске грешке или заборав да покренете API сервер. #### Брза Реч О Крос-Домен Магији Можда се питате: "Како моја веб апликација комуницира са овим API сервером кад они раде на различитим портовима?" Добро питање! Ово је нешто са чим се сваки веб програмер пре или касније сусреће. > 🔒 **Безбедност Крос-Домена**: Прегледачи спроводе "политику истог порекла" да спрече неовлашћену комуникацију између различитих домена. Као безбедносна провера у Пентагону, они потврђују да је комуникација овлашћена пре одобрења преноса података. > **У нашем случају:** - Ваша веб апликација ради на `localhost:3000` (локални дев сервер) - Ваш API сервер ради на `localhost:5000` (бекенд сервер) - API сервер укључује [CORS заглавља](https://developer.mozilla.org/docs/Web/HTTP/CORS) која експлицитно овлашћују комуникацију са ваше веб апликације Ова конфигурација огледа стварни развој где фронтенд и бекенд апликације обично раде на одвојеним серверима. > 📚 **Сазнајте Више**: Зароните дубље у API-је и преузимање података уз овај обимни [Microsoft Learn модул о API-јима](https://docs.microsoft.com/learn/modules/use-apis-discover-museum-art/?WT.mc_id=academic-77807-sagibbon). ## Оживљавање Ваших Података у HTML-у Сада ћемо учинити да преузети подаци буду видљиви корисницима помоћу манипулације DOM-ом. Као процес развијања фотографија у мрачној комори, узимамо невидљиве податке и приказујемо их као нешто што корисници могу видети и са чиме могу да комуницирају. Манипулација ДОМ-ом је техника која претвара статичке веб странице у динамичке апликације које ажурирају свој садржај на основу интеракција корисника и одговора сервера. ### Избор правог алата за посао Када је у питању ажурирање вашег ХТМЛ-а са ЈаваСкриптом, имате неколико опција. Замислите их као различите алате у кутији са алатима - сваки је савршен за одређене задатке: | Метод | За шта је сјајан | Када га користити | Ниво безбедности | |--------|---------------------|----------------|--------------| | `textContent` | Безбедно приказивање корисничких података | Увек када приказујете текст | ✅ Потпуно поуздан | | `createElement()` + `append()` | Прављење сложених распореда | Креирање нових секција/листа | ✅ Неупотребљив | | `innerHTML` | Постављање ХТМЛ садржаја | ⚠️ Покушајте да избегнете овај | ❌ Ризично пословање | #### Безбедан начин приказивања текста: textContent Својство [`textContent`](https://developer.mozilla.org/docs/Web/API/Node/textContent) је ваш најбољи пријатељ када приказујете корисничке податке. Као да имате обезбеђење за вашу веб страницу - ништа штетно неће проћи: ```javascript // Безбедан, поуздан начин за ажурирање текста const balanceElement = document.getElementById('balance'); balanceElement.textContent = account.balance; ``` **Предности textContent:** - Све третира као обичан текст (спречава извршавање скрипти) - Аутоматски брише постојећи садржај - Ефикасан за једноставна ажурирања текста - Пружа уграђену заштиту од злонамерног садржаја #### Креирање динамичких ХТМЛ елемената За сложенији садржај, комбинујте [`document.createElement()`](https://developer.mozilla.org/docs/Web/API/Document/createElement) са методом [`append()`](https://developer.mozilla.org/docs/Web/API/ParentNode/append): ```javascript // Безбедан начин за креирање нових елемената const transactionItem = document.createElement('div'); transactionItem.className = 'transaction-item'; transactionItem.textContent = `${transaction.date}: ${transaction.description}`; container.append(transactionItem); ``` **Разумевање овог приступа:** - **Креира** нове ДОМ елементе програмски - **Одржава** потпуну контролу над атрибутима и садржајем елемената - **Дозвољава** сложене, угнежђене структуре елемената - **Чува** безбедност раздвајањем структуре од садржаја > ⚠️ **Безбедносно разматрање**: Иако [`innerHTML`](https://developer.mozilla.org/docs/Web/API/Element/innerHTML) се често појављује у многим туторијалима, може извршити уграђене скрипте. Као безбедносни протоколи у ЦЕРН-у који спречавају извођење неовлашћеног кода, коришћење `textContent` и `createElement` пружа сигурније алтернативе. > **Ризици од innerHTML:** - Извршава било које `