18 KiB
Izrada Bankovne Aplikacije, Dio 2: Izrada Obrasca za Prijavu i Registraciju
Pre-Lekcijski Kviz
Uvod
U gotovo svim modernim web aplikacijama možete kreirati račun kako biste imali svoj privatni prostor. Budući da više korisnika može istovremeno pristupiti web aplikaciji, potreban je mehanizam za odvojeno pohranjivanje osobnih podataka svakog korisnika i odabir koje informacije prikazati. Nećemo pokrivati kako sigurno upravljati identitetom korisnika jer je to opsežna tema sama po sebi, ali osigurat ćemo da svaki korisnik može kreirati jedan (ili više) bankovnih računa u našoj aplikaciji.
U ovom dijelu koristit ćemo HTML obrasce za dodavanje prijave i registracije u našu web aplikaciju. Vidjet ćemo kako programatski poslati podatke na server API i na kraju kako definirati osnovna pravila validacije za korisničke unose.
Preduvjeti
Potrebno je da ste završili HTML predloške i usmjeravanje web aplikacije za ovu lekciju. Također trebate instalirati Node.js i pokrenuti server API lokalno kako biste mogli slati podatke za kreiranje računa.
Napomena Imat ćete dva terminala koja rade istovremeno, kako je navedeno u nastavku:
- Za glavnu bankovnu aplikaciju koju smo izradili u lekciji HTML predlošci i usmjeravanje
- Za Bank APP server API koji smo upravo postavili.
Potrebno je da oba servera budu pokrenuta kako biste mogli pratiti ostatak lekcije. Oni slušaju na različitim portovima (port 3000
i port 5000
), tako da bi sve trebalo raditi bez problema.
Možete testirati da li server radi ispravno izvršavanjem ove naredbe u terminalu:
curl http://localhost:5000/api
# -> should return "Bank API v1.0.0" as a result
Obrazac i kontrole
Element <form>
obuhvaća dio HTML dokumenta gdje korisnik može unositi i slati podatke putem interaktivnih kontrola. Postoji mnogo različitih korisničkih sučelja (UI) kontrola koje se mogu koristiti unutar obrasca, a najčešće su <input>
i <button>
elementi.
Postoji mnogo različitih tipova <input>
elemenata. Na primjer, za kreiranje polja gdje korisnik može unijeti svoje korisničko ime možete koristiti:
<input id="username" name="username" type="text">
Atribut name
koristit će se kao naziv svojstva kada se podaci obrasca šalju. Atribut id
koristi se za povezivanje <label>
elementa s kontrolom obrasca.
Pogledajte cijeli popis
<input>
tipova i ostalih kontrola obrasca kako biste dobili ideju o svim nativnim UI elementima koje možete koristiti pri izradi sučelja.
✅ Napomena da je <input>
prazan element kojem ne biste trebali dodavati odgovarajuću zatvarajuću oznaku. Možete koristiti samostalnu <input/>
notaciju, ali nije obavezno.
Element <button>
unutar obrasca je malo poseban. Ako ne odredite njegov atribut type
, automatski će poslati podatke obrasca na server kada se pritisne. Evo mogućih vrijednosti za type
:
submit
: Zadano ponašanje unutar<form>
, gumb pokreće akciju slanja obrasca.reset
: Gumb resetira sve kontrole obrasca na njihove početne vrijednosti.button
: Ne dodjeljuje zadano ponašanje kada se gumb pritisne. Možete mu dodijeliti prilagođene akcije pomoću JavaScripta.
Zadatak
Započnimo dodavanjem obrasca u predložak login
. Trebat ćemo polje za korisničko ime i gumb Prijava.
<template id="login">
<h1>Bank App</h1>
<section>
<h2>Login</h2>
<form id="loginForm">
<label for="username">Username</label>
<input id="username" name="user" type="text">
<button>Login</button>
</form>
</section>
</template>
Ako pažljivo pogledate, primijetit ćete da smo ovdje dodali i <label>
element. <label>
elementi koriste se za dodavanje naziva UI kontrolama, poput našeg polja za korisničko ime. Oznake su važne za čitljivost vaših obrazaca, ali dolaze i s dodatnim prednostima:
- Povezivanjem oznake s kontrolom obrasca pomaže korisnicima koji koriste asistivne tehnologije (poput čitača ekrana) da razumiju koje podatke trebaju unijeti.
- Možete kliknuti na oznaku kako biste izravno stavili fokus na povezani unos, što olakšava pristup na uređajima s dodirnim zaslonom.
Pristupačnost na webu vrlo je važna tema koja se često zanemaruje. Zahvaljujući semantičkim HTML elementima nije teško kreirati pristupačan sadržaj ako ih pravilno koristite. Možete pročitati više o pristupačnosti kako biste izbjegli uobičajene pogreške i postali odgovoran programer.
Sada ćemo dodati drugi obrazac za registraciju, odmah ispod prethodnog:
<hr/>
<h2>Register</h2>
<form id="registerForm">
<label for="user">Username</label>
<input id="user" name="user" type="text">
<label for="currency">Currency</label>
<input id="currency" name="currency" type="text" value="$">
<label for="description">Description</label>
<input id="description" name="description" type="text">
<label for="balance">Current balance</label>
<input id="balance" name="balance" type="number" value="0">
<button>Register</button>
</form>
Koristeći atribut value
možemo definirati zadanu vrijednost za određeni unos.
Primijetite također da unos za balance
ima tip number
. Izgleda li drugačije od ostalih unosa? Pokušajte interaktivno raditi s njim.
✅ Možete li navigirati i interaktivno raditi s obrascima koristeći samo tipkovnicu? Kako biste to učinili?
Slanje podataka na server
Sada kada imamo funkcionalno korisničko sučelje, sljedeći korak je slanje podataka na naš server. Napravimo brzi test koristeći naš trenutni kod: što se događa ako kliknete na gumb Prijava ili Registracija?
Primijetili ste promjenu u URL sekciji vašeg preglednika?
Zadana akcija za <form>
je slanje obrasca na trenutni URL servera koristeći GET metodu, dodajući podatke obrasca izravno u URL. Ova metoda ima nekoliko nedostataka:
- Podaci koji se šalju su vrlo ograničeni veličinom (oko 2000 znakova)
- Podaci su izravno vidljivi u URL-u (nije idealno za lozinke)
- Ne radi s prijenosom datoteka
Zato možete promijeniti metodu na POST metodu koja šalje podatke obrasca na server u tijelu HTTP zahtjeva, bez prethodnih ograničenja.
Iako je POST najčešće korištena metoda za slanje podataka, u nekim specifičnim scenarijima je poželjno koristiti GET metodu, primjerice kod implementacije polja za pretraživanje.
Zadatak
Dodajte action
i method
svojstva obrascu za registraciju:
<form id="registerForm" action="//localhost:5000/api/accounts" method="POST">
Sada pokušajte registrirati novi račun s vašim imenom. Nakon klika na gumb Registracija trebali biste vidjeti nešto poput ovoga:
Ako sve ide kako treba, server bi trebao odgovoriti na vaš zahtjev s JSON odgovorom koji sadrži podatke o kreiranom računu.
✅ Pokušajte se ponovno registrirati s istim imenom. Što se događa?
Slanje podataka bez osvježavanja stranice
Kao što ste vjerojatno primijetili, postoji mali problem s pristupom koji smo upravo koristili: prilikom slanja obrasca izlazimo iz naše aplikacije i preglednik se preusmjerava na URL servera. Pokušavamo izbjeći sva osvježavanja stranica s našom web aplikacijom jer izrađujemo Jednostranu aplikaciju (SPA).
Kako bismo poslali podatke obrasca na server bez prisilnog osvježavanja stranice, moramo koristiti JavaScript kod. Umjesto da stavimo URL u svojstvo action
elementa <form>
, možete koristiti bilo koji JavaScript kod s prefiksom javascript:
za izvođenje prilagođene akcije. Koristeći ovo također znači da ćete morati implementirati neke zadatke koji su se prethodno automatski obavljali od strane preglednika:
- Dohvatiti podatke obrasca
- Pretvoriti i kodirati podatke obrasca u odgovarajući format
- Kreirati HTTP zahtjev i poslati ga na server
Zadatak
Zamijenite action
obrasca za registraciju s:
<form id="registerForm" action="javascript:register()">
Otvorite app.js
i dodajte novu funkciju nazvanu register
:
function register() {
const registerForm = document.getElementById('registerForm');
const formData = new FormData(registerForm);
const data = Object.fromEntries(formData);
const jsonData = JSON.stringify(data);
}
Ovdje dohvaćamo element obrasca koristeći getElementById()
i koristimo pomoćnika FormData
za izdvajanje vrijednosti iz kontrola obrasca kao skup ključ/vrijednost parova. Zatim pretvaramo podatke u običan objekt koristeći Object.fromEntries()
i na kraju serijaliziramo podatke u JSON, format koji se često koristi za razmjenu podataka na webu.
Podaci su sada spremni za slanje na server. Kreirajte novu funkciju nazvanu createAccount
:
async function createAccount(account) {
try {
const response = await fetch('//localhost:5000/api/accounts', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: account
});
return await response.json();
} catch (error) {
return { error: error.message || 'Unknown error' };
}
}
Što ova funkcija radi? Prvo, primijetite ključnu riječ async
ovdje. To znači da funkcija sadrži kod koji će se izvršavati asinkrono. Kada se koristi zajedno s ključnom riječi await
, omogućuje čekanje na izvršenje asinkronog koda - poput čekanja na odgovor servera ovdje - prije nastavka.
Evo kratkog videa o korištenju async/await
:
🎥 Kliknite na sliku iznad za video o async/await.
Koristimo fetch()
API za slanje JSON podataka na server. Ova metoda uzima 2 parametra:
- URL servera, pa ovdje vraćamo
//localhost:5000/api/accounts
. - Postavke zahtjeva. Tu postavljamo metodu na
POST
i pružamobody
za zahtjev. Budući da šaljemo JSON podatke na server, također moramo postaviti zaglavljeContent-Type
naapplication/json
kako bi server znao kako interpretirati sadržaj.
Budući da će server odgovoriti na zahtjev s JSON-om, možemo koristiti await response.json()
za parsiranje JSON sadržaja i vraćanje rezultirajućeg objekta. Napomena da je ova metoda asinkrona, pa ovdje koristimo ključnu riječ await
prije vraćanja kako bismo osigurali da se eventualne greške tijekom parsiranja također uhvate.
Sada dodajte malo koda u funkciju register
kako biste pozvali createAccount()
:
const result = await createAccount(jsonData);
Budući da koristimo ključnu riječ await
ovdje, moramo dodati ključnu riječ async
prije funkcije register:
async function register() {
Na kraju, dodajmo neke logove kako bismo provjerili rezultat. Konačna funkcija trebala bi izgledati ovako:
async function register() {
const registerForm = document.getElementById('registerForm');
const formData = new FormData(registerForm);
const jsonData = JSON.stringify(Object.fromEntries(formData));
const result = await createAccount(jsonData);
if (result.error) {
return console.log('An error occurred:', result.error);
}
console.log('Account created!', result);
}
To je bilo malo duže, ali stigli smo! Ako otvorite alate za razvoj preglednika i pokušate registrirati novi račun, ne biste trebali vidjeti nikakvu promjenu na web stranici, ali poruka će se pojaviti u konzoli potvrđujući da sve radi.
✅ Mislite li da se podaci šalju na server sigurno? Što ako netko uspije presresti zahtjev? Možete pročitati o HTTPS kako biste saznali više o sigurnoj komunikaciji podataka.
Validacija podataka
Ako pokušate registrirati novi račun bez postavljanja korisničkog imena, možete vidjeti da server vraća grešku sa statusnim kodom 400 (Loš Zahtjev).
Prije slanja podataka na server dobra je praksa validirati podatke obrasca unaprijed kad god je to moguće, kako biste bili sigurni da šaljete valjan zahtjev. HTML5 kontrole obrasca pružaju ugrađenu validaciju koristeći razne atribute:
required
: polje mora biti ispunjeno, inače se obrazac ne može poslati.minlength
imaxlength
: definiraju minimalni i maksimalni broj znakova u tekstualnim poljima.min
imax
: definiraju minimalnu i maksimalnu vrijednost numeričkog polja.type
: definira vrstu očekivanih podataka, poputnumber
,email
,file
ili ostalih ugrađenih tipova. Ovaj atribut također može promijeniti vizualni prikaz kontrole obrasca.pattern
: omogućuje definiranje regularnog izraza za testiranje valjanosti unesenih podataka.
Savjet: možete prilagoditi izgled svojih kontrola obrasca ovisno o tome jesu li valjane ili ne koristeći CSS pseudo-klase
:valid
i:invalid
.
Zadatak
Postoje 2 obavezna polja za kreiranje valjanog novog računa: korisničko ime i valuta, dok su ostala polja opcionalna. Ažurirajte HTML forme koristeći atribut required
i tekst u oznaci polja kako bi:
<label for="user">Username (required)</label>
<input id="user" name="user" type="text" required>
...
<label for="currency">Currency (required)</label>
<input id="currency" name="currency" type="text" value="$" required>
Iako ova konkretna implementacija servera ne nameće specifična ograničenja na maksimalnu duljinu polja, uvijek je dobra praksa definirati razumna ograničenja za unos teksta od strane korisnika.
Dodajte atribut maxlength
u tekstualna polja:
<input id="user" name="user" type="text" maxlength="20" required>
...
<input id="currency" name="currency" type="text" value="$" maxlength="5" required>
...
<input id="description" name="description" type="text" maxlength="100">
Sada, ako pritisnete gumb Registriraj se i neko polje ne poštuje pravilo validacije koje smo definirali, trebali biste vidjeti nešto poput ovoga:
Validacija poput ove, koja se obavlja prije slanja podataka na server, naziva se validacija na strani klijenta. No, imajte na umu da nije uvijek moguće obaviti sve provjere bez slanja podataka. Na primjer, ovdje ne možemo provjeriti postoji li već račun s istim korisničkim imenom bez slanja zahtjeva serveru. Dodatna validacija koja se obavlja na serveru naziva se validacija na strani servera.
Obično je potrebno implementirati obje vrste validacije, a dok validacija na strani klijenta poboljšava korisničko iskustvo pružanjem trenutne povratne informacije korisniku, validacija na strani servera ključna je za osiguranje da su podaci korisnika koje obrađujete ispravni i sigurni.
🚀 Izazov
Prikazati poruku o grešci u HTML-u ako korisnik već postoji.
Evo primjera kako konačna stranica za prijavu može izgledati nakon malo stiliziranja:
Kviz nakon predavanja
Pregled i samostalno učenje
Razvijatelji su postali vrlo kreativni u svojim naporima za izradu formi, posebno u vezi strategija validacije. Saznajte više o različitim tokovima formi pregledavajući CodePen; možete li pronaći neke zanimljive i inspirativne forme?
Zadatak
Stilizirajte svoju bankovnu aplikaciju
Odricanje od odgovornosti:
Ovaj dokument je preveden korištenjem AI usluge za prevođenje Co-op Translator. Iako nastojimo osigurati točnost, imajte na umu da automatski prijevodi mogu sadržavati pogreške ili netočnosti. Izvorni dokument na izvornom jeziku treba smatrati mjerodavnim izvorom. Za ključne informacije preporučuje se profesionalni prijevod od strane stručnjaka. Ne preuzimamo odgovornost za bilo kakve nesporazume ili pogrešne interpretacije proizašle iz korištenja ovog prijevoda.