You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
Web-Dev-For-Beginners/translations/sr/5-browser-extension/2-forms-browsers-local-storage/README.md

25 KiB

Пројекат проширења прегледача, део 2: Позив API-ја, коришћење локалног складишта

Квиз пре предавања

Квиз пре предавања

Увод

Сећате ли се проширења за прегледач које сте почели да правите? Тренутно имате лепо дизајниран формулар, али је у суштини статичан. Данас ћемо га оживети повезивањем са стварним подацима и додавањем меморије.

Размислите о рачунарима за контролу мисије Аполо - они нису само приказивали фиксне информације. Стално су комуницирали са свемирским летелицама, ажурирали телеметријске податке и памтили критичне параметре мисије. Управо такав динамичан систем градимо данас. Ваше проширење ће се повезати са интернетом, преузети стварне податке о животној средини и запамтити ваша подешавања за следећи пут.

Интеграција API-ја може звучати сложено, али у суштини се ради о томе да научите свој код како да комуницира са другим сервисима. Било да преузимате податке о времену, фидове са друштвених мрежа или информације о угљеничном отиску, као што ћемо данас радити, све се своди на успостављање ових дигиталних веза. Такође ћемо истражити како прегледачи могу да чувају информације - слично као што библиотеке користе каталоге картица за памћење где се налазе књиге.

На крају овог предавања, имаћете проширење за прегледач које преузима стварне податке, чува корисничке преференције и пружа глатко корисничко искуство. Хајде да почнемо!

Пратите нумерисане сегменте у одговарајућим датотекама да бисте знали где да поставите свој код.

Поставите елементе за манипулацију у проширењу

Пре него што ваш JavaScript може да манипулише интерфејсом, потребно је да има референце на одређене HTML елементе. Замислите то као телескоп који треба да буде усмерен на одређене звезде - пре него што је Галилео могао да проучава Јупитерове месеце, морао је да лоцира и фокусира се на сам Јупитер.

У вашој датотеци index.js, креираћемо const променљиве које хватају референце на сваки важан елемент формулара. Ово је слично начину на који научници означавају своју опрему - уместо да сваки пут траже кроз целу лабораторију, могу директно приступити ономе што им је потребно.

// form fields
const form = document.querySelector('.form-data');
const region = document.querySelector('.region-name');
const apiKey = document.querySelector('.api-key');

// results
const errors = document.querySelector('.errors');
const loading = document.querySelector('.loading');
const results = document.querySelector('.result-container');
const usage = document.querySelector('.carbon-usage');
const fossilfuel = document.querySelector('.fossil-fuel');
const myregion = document.querySelector('.my-region');
const clearBtn = document.querySelector('.clear-btn');

Шта овај код ради:

  • Хвата елементе формулара користећи document.querySelector() са CSS селекторима класе
  • Креира референце на поља за унос имена региона и API кључа
  • Успоставља везе са елементима за приказ резултата података о угљеничној потрошњи
  • Поставља приступ елементима корисничког интерфејса као што су индикатори учитавања и поруке о грешкама
  • Чува сваку референцу елемента у const променљивој ради лакшег поновног коришћења у вашем коду

Додајте слушаоце догађаја

Сада ћемо учинити да ваше проширење реагује на корисничке акције. Слушаоци догађаја су начин на који ваш код прати интеракције корисника. Замислите их као оператере у раним телефонским централама - они су слушали долазне позиве и повезивали праве кругове када је неко желео да успостави везу.

form.addEventListener('submit', (e) => handleSubmit(e));
clearBtn.addEventListener('click', (e) => reset(e));
init();

Разумевање ових концепата:

  • Додаје слушаоца за слање формулара који се активира када корисници притисну Enter или кликну на дугме за слање
  • Повезује слушаоца клика на дугме за брисање ради ресетовања формулара
  • Прослеђује објекат догађаја (e) функцијама за обраду ради додатне контроле
  • Позива функцију init() одмах ради постављања почетног стања вашег проширења

Обратите пажњу на скраћену синтаксу стреличастих функција која се овде користи. Овај модеран приступ у JavaScript-у је чистији од традиционалних израза функција, али оба раде једнако добро!

Направите функције за иницијализацију и ресетовање

Хајде да креирамо логику иницијализације за ваше проширење. Функција init() је као навигациони систем брода који проверава своје инструменте - одређује тренутно стање и прилагођава интерфејс у складу с тим. Проверава да ли је неко раније користио ваше проширење и учитава његова претходна подешавања.

Функција reset() пружа корисницима нови почетак - слично као што научници ресетују своје инструменте између експеримената како би осигурали чисте податке.

function init() {
	// Check if user has previously saved API credentials
	const storedApiKey = localStorage.getItem('apiKey');
	const storedRegion = localStorage.getItem('regionName');

	// Set extension icon to generic green (placeholder for future lesson)
	// TODO: Implement icon update in next lesson

	if (storedApiKey === null || storedRegion === null) {
		// First-time user: show the setup form
		form.style.display = 'block';
		results.style.display = 'none';
		loading.style.display = 'none';
		clearBtn.style.display = 'none';
		errors.textContent = '';
	} else {
		// Returning user: load their saved data automatically
		displayCarbonUsage(storedApiKey, storedRegion);
		results.style.display = 'none';
		form.style.display = 'none';
		clearBtn.style.display = 'block';
	}
}

function reset(e) {
	e.preventDefault();
	// Clear stored region to allow user to choose a new location
	localStorage.removeItem('regionName');
	// Restart the initialization process
	init();
}

Разлагање онога што се овде дешава:

  • Преузима сачувани API кључ и регион из локалног складишта прегледача
  • Проверава да ли је ово први пут да корисник користи проширење (нема сачуваних акредитива) или се враћа
  • Приказује формулар за подешавање за нове кориснике и сакрива друге елементе интерфејса
  • Аутоматски учитава сачуване податке за кориснике који се враћају и приказује опцију за ресетовање
  • Управља стањем корисничког интерфејса на основу доступних података

Кључни концепти о локалном складишту:

  • Чува податке између сесија прегледача (за разлику од session storage-а)
  • Складишти податке као парове кључ-вредност користећи getItem() и setItem()
  • Враћа null када не постоје подаци за дати кључ
  • Пружа једноставан начин за памћење корисничких преференција и подешавања

💡 Разумевање складишта прегледача: LocalStorage је као да вашем проширењу дате трајну меморију. Замислите како је древна библиотека у Александрији чувала свитке - информације су остале доступне чак и када су научници одлазили и враћали се.

Кључне карактеристике:

  • Чува податке чак и након што затворите прегледач
  • Опстаје након рестарта рачунара и пада прегледача
  • Пружа значајан простор за складиштење корисничких преференција
  • Нуди тренутан приступ без кашњења у мрежи

Важно упозорење: Ваше проширење за прегледач има своје изоловано локално складиште које је одвојено од редовних веб страница. Ово пружа сигурност и спречава конфликте са другим веб сајтовима.

Можете видети своје сачуване податке отварањем алатки за програмере у прегледачу (F12), преласком на картицу Application и проширивањем секције Local Storage.

Прозор локалног складишта

⚠️ Сигурносно разматрање: У производним апликацијама, чување API кључева у локалном складишту представља безбедносни ризик јер JavaScript може приступити овим подацима. За потребе учења, овај приступ је у реду, али праве апликације треба да користе сигурно серверско складиштење за осетљиве акредитиве.

Обрада слања формулара

Сада ћемо обрадити шта се дешава када неко пошаље ваш формулар. По подразумеваној вредности, прегледачи поново учитавају страницу када се формулар пошаље, али ми ћемо пресрести ово понашање како бисмо створили глатко искуство.

Овај приступ одражава начин на који контролна мисија обрађује комуникацију са свемирским летелицама - уместо да ресетује цео систем за сваку трансмисију, они одржавају континуирану операцију док обрађују нове информације.

Креирајте функцију која хвата догађај слања формулара и извлачи унос корисника:

function handleSubmit(e) {
	e.preventDefault();
	setUpUser(apiKey.value, region.value);
}

У горе наведеном, ми смо:

  • Спречили подразумевано понашање слања формулара које би освежило страницу
  • Извукли вредности уноса корисника из поља за API кључ и регион
  • Проследили податке из формулара функцији setUpUser() за обраду
  • Одржали понашање апликације на једној страници избегавајући освежавање странице

Запамтите да ваша HTML поља формулара укључују атрибут required, тако да прегледач аутоматски проверава да ли корисници пружају и API кључ и регион пре него што ова функција почне да ради.

Поставите корисничке преференције

Функција setUpUser је одговорна за чување акредитива корисника и покретање првог API позива. Ово ствара глатку транзицију од подешавања до приказивања резултата.

function setUpUser(apiKey, regionName) {
	// Save user credentials for future sessions
	localStorage.setItem('apiKey', apiKey);
	localStorage.setItem('regionName', regionName);
	
	// Update UI to show loading state
	loading.style.display = 'block';
	errors.textContent = '';
	clearBtn.style.display = 'block';
	
	// Fetch carbon usage data with user's credentials
	displayCarbonUsage(apiKey, regionName);
}

Корак по корак, ево шта се дешава:

  • Чува API кључ и име региона у локалном складишту за будућу употребу
  • Приказује индикатор учитавања како би обавестио кориснике да се подаци преузимају
  • Брише све претходне поруке о грешкама са приказа
  • Открива дугме за брисање како би корисници могли касније да ресетују своја подешавања
  • Покреће API позив за преузимање стварних података о угљеничној потрошњи

Ова функција ствара беспрекорно корисничко искуство управљајући и трајним чувањем података и ажурирањем корисничког интерфејса у једној координисаној акцији.

Приказ података о угљеничној потрошњи

Сада ћемо повезати ваше проширење са спољним изворима података преко API-ја. Ово трансформише ваше проширење из самосталног алата у нешто што може приступити информацијама у реалном времену са интернета.

Разумевање API-ја

API-ји су начин на који различите апликације комуницирају једна са другом. Замислите их као телеграфски систем који је повезивао удаљене градове у 19. веку - оператери би слали захтеве удаљеним станицама и добијали одговоре са траженим информацијама. Сваки пут када проверите друштвене мреже, поставите питање гласовном асистенту или користите апликацију за доставу, API-ји омогућавају ове размене података.

Кључни концепти о REST API-јима:

  • REST означава 'Representational State Transfer'
  • Користи стандардне HTTP методе (GET, POST, PUT, DELETE) за интеракцију са подацима
  • Враћа податке у предвидљивим форматима, обично JSON
  • Пружа конзистентне, URL-базиране крајње тачке за различите типове захтева

CO2 Signal API који ћемо користити пружа податке о угљеничној интензивности електричних мрежа широм света у реалном времену. Ово помаже корисницима да разумеју утицај њихове потрошње електричне енергије на животну средину!

💡 Разумевање асинхроног JavaScript-а: Кључна реч async омогућава вашем коду да истовремено обрађује више операција. Када затражите податке са сервера, не желите да се цело проширење замрзне - то би било као да контрола ваздушног саобраћаја заустави све операције док чека одговор једног авиона.

Кључне предности:

  • Одржава одзивност проширења док се подаци учитавају
  • Омогућава наставак извршавања другог кода током мрежних захтева
  • Побољшава читљивост кода у поређењу са традиционалним обрасцима повратних позива
  • Омогућава елегантно руковање грешкама у случају проблема са мрежом

Ево кратког видеа о async:

Async и Await за управљање обећањима

🎥 Кликните на слику изнад за видео о async/await.

Креирајте функцију за преузимање и приказ података о угљеничној потрошњи:

// Modern fetch API approach (no external dependencies needed)
async function displayCarbonUsage(apiKey, region) {
	try {
		// Fetch carbon intensity data from CO2 Signal API
		const response = await fetch('https://api.co2signal.com/v1/latest', {
			method: 'GET',
			headers: {
				'auth-token': apiKey,
				'Content-Type': 'application/json'
			},
			// Add query parameters for the specific region
			...new URLSearchParams({ countryCode: region }) && {
				url: `https://api.co2signal.com/v1/latest?countryCode=${region}`
			}
		});

		// Check if the API request was successful
		if (!response.ok) {
			throw new Error(`API request failed: ${response.status}`);
		}

		const data = await response.json();
		const carbonData = data.data;

		// Calculate rounded carbon intensity value
		const carbonIntensity = Math.round(carbonData.carbonIntensity);

		// Update the user interface with fetched data
		loading.style.display = 'none';
		form.style.display = 'none';
		myregion.textContent = region.toUpperCase();
		usage.textContent = `${carbonIntensity} grams (grams CO₂ emitted per kilowatt hour)`;
		fossilfuel.textContent = `${carbonData.fossilFuelPercentage.toFixed(2)}% (percentage of fossil fuels used to generate electricity)`;
		results.style.display = 'block';

		// TODO: calculateColor(carbonIntensity) - implement in next lesson

	} catch (error) {
		console.error('Error fetching carbon data:', error);
		
		// Show user-friendly error message
		loading.style.display = 'none';
		results.style.display = 'none';
		errors.textContent = 'Sorry, we couldn\'t fetch data for that region. Please check your API key and region code.';
	}
}

Разлагање онога што се овде дешава:

  • Користи модерни fetch() API уместо спољних библиотека као што је Axios за чистији код без зависности
  • Примењује правилну проверу грешака са response.ok како би рано открио неуспехе API-ја
  • Рукује асинхроним операцијама са async/await ради читљивијег тока кода
  • Аутентификује се са CO2 Signal API-јем користећи заглавље auth-token
  • Парсира JSON одговор и извлачи информације о угљеничној интензивности
  • Ажурира више елемената корисничког интерфејса са форматираним подацима о животној средини
  • Пружа кориснички пријатељске поруке о грешкама када API позиви не успеју

Кључни модерни JavaScript концепти који су демонстрирани:

  • Шаблонски литерали са ${} синтаксом за чисто форматирање стрингова
  • Руковање грешкама са try/catch блоковима за робусне апликације
  • Async/await образац за елегантно руковање мрежним захтевима
  • Деструктурирање објеката за извлачење специфичних података из API одговора
  • Ланчање метода за више манипулација DOM-ом

Ова функција демонстрира неколико важних концепата веб развоја - комуникацију са спољним серверима, руковање аутентификацијом, обраду података, ажурирање интерфе У овој лекцији сте научили о LocalStorage-у и API-јевима, оба веома корисна за професионалног веб програмера. Можете ли размислити о томе како ове две ствари функционишу заједно? Размислите о томе како бисте осмислили веб сајт који би чувао ставке које ће користити API.

Задатак

Усвојите API


Одрицање од одговорности:
Овај документ је преведен помоћу услуге за превођење вештачке интелигенције Co-op Translator. Иако настојимо да обезбедимо тачност, молимо вас да имате у виду да аутоматски преводи могу садржати грешке или нетачности. Оригинални документ на његовом изворном језику треба сматрати меродавним извором. За критичне информације препоручује се професионални превод од стране људи. Не преузимамо одговорност за било каква погрешна тумачења или неспоразуме који могу настати услед коришћења овог превода.