Web aplikacije¶
Web aplikacija je program koji se izvršava na web (http) serveru. Za razliku od tradicionalnih, desktop aplikacija koje se pokreću vašim operativnim sistemom, web aplikacije se najčešće pokreću uz pomoć “web browser” programa (Chrome, Firefox, Opera, itd…).
Web aplikacije imaju više prednosti nad desktop aplikacijama. Pošto se izvršavaju na brauzerima ne moraju se prilagođavati različitim operativnim sistemima, ista aplikacija radi na svim platformama. Web aplikacije ne moraju da se distribuiraju i instaliraju na svakom računaru na kojem su potrebne. One se instaliraju samo na jednom serveru kojem mogu da pristupaju svi korisnici aplikacije, bilo gde da se nalaze. Na taj način korisnici uvek izvršavaju poslednju, na serveru instaliranu verziju aplikacije. Web aplikacije mogu biti distupne na svim hardverskim uređajima: desktopovima, laptopovima, tabletima, smart telefonima, kao i svim drugim uređajima koji se mogu povezati na internet putem http protokola.
U daljem tekstu ćemo se upoznati sa bazičnim tehnologijama koje se koriste pri razvoju web aplikacija.
Komponente web aplikacije¶
Sledeća slika prikazuje arhitekturu (strukturu) moderno dizajniranih web aplikacija.

Na klijentskoj strani se koriste tri osnovne tehnologije:
- CSS
- HTML
- JavaScript
JavaScript ima višestruku ulogu:
- Za programiranje komunikacije sa serverom
- Kao pomoć za dinamičke promene u UI
- Kao realizaciju dela biznis logike
HTML ima jednu jedinu ulogu:
- Definiše layout komponenti u UI
CSS takođe ime samo jednu ulogu:
- Definiše način prikaza komponenti UI
Na serverskoj strani se najčeće koriste dve tehnologije:
- Programski jezik za programiranje komunikacije sa klijentom i realizaciju biznis logike
- Baza podataka za permanentno skaldištenje podataka
Aplikacija na jednoj stranici (SPA)¶
Sledeća slika prikazuje tradicionalan i moderan način komunikacije između servera i klijenta.

U tradicionalnom načinu, svaki put kada se klijent obrati serveru ovaj mu isporuči čitavu stranicu sa svim sadržajima.
U modernom prustupu, server samo jedanput, na početku, isporuči klijentu osnovnu stranicu ( obično index.html ). Kada klijent pravi dalje zahteve server mu šalje samo tražene parcijalne podatke (Ajax mehanizmom), a ne cele stranice kao u tradicionalnom načinu. Tako se postiže mnogo veća brzina rada aplikacije.
Primer web aplikacije¶
Sada ćemo analizirati jedan primer aplikacije koja može da nam posluži kao okvir (framework) za buduće aplikacije (projekte).
Namena ove aplikacije je da nam demonstrira implementaciju SPA (Single Page Application) modela.
Zadatak aplikacije:
Početna stranica sadrži ulazna polja (<input>) koja prihvataju metod, putanju i sadržaj Ajax zehteva. Podaci iz ovih polja će klikom na dugme “Pošalji zahtev” biti prosleđeni serveru, koji će nakon obrade zahteva vratiti odgovor sa istim tim podacima kao potvrdu da je primio i razumeo zahtev.
Naša aplikacija će se sastojati od četiri komponente:
- Početne stranice (index.html)
- Servera aplikacije (app.py)
- JavaScript programa (app.js)
- CSS fajla (app.css)
Jedino nedostaje baza podataka pa da imamo tzv. “full stack” aplikaciju.
Početna stranica (index.html)¶
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<meta name="author" content="Milan Popovic">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>SimpleWebApp</title>
<link rel="stylesheet" href="app.css">
<script src="app.js"></script>
</head>
<body>
<h1>Ajax zahtev</h1>
Metod<br><input id="metod" size=40><br><br>
Putanja<br><input id="putanja" size=40><br><br>
Podaci<br><input id="podaci" size=40><br><br>
<button onclick=PosaljiAjaxZahtev()>Ajax zahtev</button>
<button onclick=ObrisiOdgovor()>Obriši odgovor</button>
<div id="odgovor"></div>
</body>
</html>
CSS fajl (app.css)¶
button {
background-color: blue;
color: white;
}
h1 {
color: blue;
}
body {
margin-left: 20%;
margin-top: 5%;
}
#odgovor {
color: red
}
JavaScript program (app.js)¶
function AjaxZahtev(metod, putanja, podaci, callback) {
var req = new XMLHttpRequest();
req.open(metod, putanja, true);
req.addEventListener("load", function() {
if (req.status < 400) {
callback(req.responseText);
}
else {
callback(new Error("Request failed: " + req.statusText));
}
});
req.addEventListener("error", function() {
callback(new Error("Network error"));
});
req.send(podaci || null);
}
function PosaljiAjaxZahtev(){
var metod = document.getElementById("metod").value;
var putanja = document.getElementById("putanja").value;
var podaci = document.getElementById("podaci").value;
AjaxZahtev(metod, putanja, podaci, PrikaziOdgovor);
}
function PrikaziOdgovor(odgovor){
document.getElementById("odgovor").innerHTML = "<h1>Odgovor servera</h1><p>"+odgovor+"</p>";
}
function ObrisiOdgovor(){
document.getElementById("odgovor").innerHTML = "";
}
Python server aplikacije (app.py)¶
import http.server, os, json
class Handler(http.server.BaseHTTPRequestHandler):
def _set_headers(self, type):
self.send_response(200)
self.send_header('Content-type', type)
self.end_headers()
def do_GET(self):
filename = self.path.split("/")[-1]
if filename == "" : filename = "index.html"
if os.access(filename, os.R_OK) and not os.path.isdir(filename):
ext = filename.split(".")[-1] # Klijent zahteva fajl
mode = "r"
if ext in ["html","htm"]: content_type = "text/html"
elif ext in ["txt","js","py","php"]: content_type = "text/plain"
elif ext in ["css"]: content_type = "text/css"
elif ext in ["ico","jpg","jpeg","png","gif"]:
content_type = "image/x-icon"
mode = "rb"
content = open(filename, mode).read()
if mode == "r": content = str.encode(content)
self._set_headers(content_type)
self.wfile.write(content)
else: # Ajax zahtev
odgovor = {"metod":"GET", "path": self.path}
self._set_headers("text/json")
self.wfile.write(str.encode(json.dumps(odgovor)))
def do_POST(self):
putanja = self.path
metod = self.command
duzina_podataka = int(self.headers['Content-Length'])
podaci = self.rfile.read(duzina_podataka).decode("utf-8")
odgovor = {"metod": metod, "putanja": putanja, "podaci": podaci}
self._set_headers("text/json")
self.wfile.write(str.encode(json.dumps(odgovor)))
try:
httpd = http.server.HTTPServer(('',8080), Handler)
print("Server startovan...port: 8080")
httpd.serve_forever()
except:
print("Server stopiran")
U celom ovom programu najinteresantniji deo su metode definisane u Handler klasi.
Metoda _set_headres služi da server pomoću nje pošalje klijentu potvrdu da je primio zahtev i tip ( format ) sadržaja koji će poslati klijentu kao odgovor na njegov zahtev.
Metode do_GET i do_POST su metode koje obrađuju zahteve klijenta.
GET i POST su dva osnovna metoda pomoću kojih klijent može da uputi zahtev serveru:
- GET - Zahteva neki serverov resurs ( definisan pomoću URL adrese - putanje ) uz dodatne podatke koji su deo URL stringa.
- POST - Šalje serveru podatke koje će obraditi neki serverov resurs ( definisan pomoću URL adrese-putanje )
Za vežbu, analizirajte prikazane komponente, eksperimentišite sa promenama u komponentama. Krajnji cilj je da razumete mehanizam funkcionisanja web aplikacije. Nemojte se plašiti ako dobro ne poznajete sintaksu jezika koji su korišćeni. O svakom od ovih jezika biće govora u narednim poglavljima.
Da bi se olakšao i ubrzao razvoj web aplikacija često se koriste takoznani frejmvorci (frameworks). To su zapravo unapred programiranji elementi web aplikacija pogodni za nadogradnju od strane web developera. Za svaki od programskih jezika izrađeno je više takvih frejmvorka.
U Pythonu je, takođe, u upotrebi više frejmvorka. Najpoznatiji su Django za složenije i Flask za manje složene aplikacije.
Dobar tutorijal i detaljan opis za Django možete da nađete na adresi Django Slično, za Flask tutorijal i detaljan opis pogledajte na Flask.
Na sledećem sajtu možete da vidite listu popularnosti najpoznatijih frejmvork-a. Lista popularnosti