Tecnologie Web
Tecnologie Web
APPUNTI + SLIDE
UNIVERSITÀ DI BOLOGNA
2023/24
1
INTRODUZIONE E BREVE STORIA DEL WORLD WIDE WEB
Il World Wide Web è un sistema ipertestuale di documenti multimediali = Insieme di contenuti collegati che per essere
letti hanno bisogno di dispositivi da cui leggere e dispositivi che contengono questi contenuti. Ci sono delle
rappresentazioni degli utenti nel web, ovvero documenti che contengono le informazioni che mi riguardano.
Distribuito e scalato su Internet
Contenuti testuali e non, sempre più dati, pensati per essere "consumati" sia da esseri umani che da applicazioni.
Una knowledge-base su cui costruire servizi sofisticati per gli utenti finali.
Il World Wide Web si basa su un'ARCHITETTURA CLIENT-SERVER:
- Il client chiede le risorse al server.
- Il server è in attesa di richieste e, ricevuta una richiesta di risorsa, la restituisce al client
- altre entità intermedie possono intervenire in questo flusso di comunicazione (es. proxy).
Il BROWSER è un CLIENT WEB in grado di visualizzare i documenti e interagire con l'utente durante la navigazione.
Il client non ha necessariamente un'interfaccia grafica ma:
- può avere interfacce diverse, es. screen reader o interfacce vocali
- non avere un'interfaccia utente, ma essere a sua volta un'applicazione che processa e combina i dati ricevuti
STATELESS → quando arriva una richiesta, invio risposta.
Alla base di WWW ci sono i tre protocolli/linguaggi:
• URI: standard per identificare in maniera generale risorse di rete e per poterle specificare all’interno di documenti
ipertestuali. Permettono di identificare le risorse in modo univoco.
• HTTP: protocollo di comunicazione STATELESS e CLIENTSERVER per l’accesso a risorse ipertestuali.
• HTML: linguaggio per la marcatura di documenti ipertestuali basato su SGML (e XML) che permette di descrivere
la struttura di un documento e le sue componenti, inclusi oggetti multimediali e link, e di visualizzare i contenuti sul
browser.
A questi si aggiungono molti altri standard, diventati sempre più centrali nello sviluppo di applicazioni Web. Tecnologie
che popolano il web:
• CSS: linguaggio di presentazione per decidere gli aspetti tipografici e di formattazione.
• JAVASCRIPT e TYPESCRIPT: linguaggio di programmazione client-side per aggiungere comportamenti dinamici
• JSON: formato "leggero" di interscambio dati basato su Javascript
Ma è sempre stato così? Come si sono evoluti e si evolvono questi standard? Quali "forze" entrano in gioco?
Quando è stato pensato il web? Nel 1989, dopo che internet era già una realtà esistente. Chi ha inventato il web? Un fisico
Tim Berners Lee che ha fatto proposta di collegare dispositivi, documenti e persone che usano dispositivi. INTERNET
DIVERSO DA WEB!
2
L'affermazione di strumenti di partecipazione attiva alla costruzione di contenuti per il web: blog, wiki, podcast, RSS,
folksonomie, ecc.
Il Web diventa quindi una piattaforma, fortemente orientata al mash-up di dati da sorgenti diverse, su cui pubblicare
contenuti con facilità ed elaborare dati.
Le applicazioni Web diventano molto più veloci, complesse ed interattive
Per quanto riguarda le tecnologie Web, due aspetti ortogonali:
- Affermazione del paradigma REST per sfruttare le caratteristiche di HTTP e creare applicazioni solide e scalabili
- Sviluppo dei linguaggi di programmazione client-side e di AJAX, che permette richieste asincrone al server e
precaricamento di dati
API WEB
Così come per i linguaggi di programmazione, un' API WEB definisce le modalità per interagire con un'applicazione
→elenca le possibili richieste e risposte che l'applicazione è in grado di gestire.
Le applicazioni, sia server-side che client side, possono quindi raccogliere i dati per poi elaborarli invocando una o più
API:
- applicazioni diverse costruite sugli stessi dati
- applicazioni di mash-up che combinano dati in formati diversi e da sorgenti diverse
SEMANTIC WEB
Idea del SEMANTIC WEB = idea di trasformare web, oltre che ad una rete di contenuti e documenti, anche in una rete di
concetti ovvero entità collegate tra loro.
Il Semantic Web usa un modello di rappresentazione dei dati basato su triple, chiamato RDF (a volte chiamato
impropriamente “linguaggio”, esistono diverse sintassi per esprimere le stesse informazioni).
Basato su triple soggetto-predicato-oggetto dette statement.
Esempio: “Umberto Eco è autore de Il Nome della Rosa” può essere espresso come affermazione RDF assegnando a:
• “Umberto Eco” il ruolo di soggetto
• “è autore di” il ruolo di predicato
• “Il Nome della Rosa” il ruolo di oggetto
3
LINKED OPEN DATA (LOD)
Linked Data riguarda l’uso del Web per creare link tipati tra risorse appartenenti a domini differenti, in modo da esprimere
relazioni e proprietà.
Obiettivo: pubblicare dati sul Web in modo che:
- siano machine-readable
- con un significato esplicitamente definito
- abbiano collegamenti verso altri insiemi di dati (dataset) esterni.
LOD è un progetto del W3C che si occupa di estendere il Web tradizionale pubblicando dataset liberi e aperti e mettendo
in relazione tra loro dati provenienti da sorgenti diverse.
WIKIDATA
WikiData (https://www.wikidata.org/ ) è una knowledge-base collaborativa, aperta e multilingua.
Costituita da item (entità) con un codice identificativo univoco e sui quali sono espresse proprietà e relazioni tramite
affermazioni.
I dati possono essere modificati direttamente e/o importanti da altre fonti, inclusa WikiPedia (così come fatto da
DBPedia)
CONCLUSIONI
Il World Wide Web ha una storia relativamente recente ma ha visto diverse evoluzioni ed involuzioni.
Da un sistema di contenuti ipertestuali si è arrivati ad un sistema di dati e applicazioni, con modalità di accesso sempre
più variegate.
Le tecnologie di base tuttavia sono sostanzialmente le stesse ma è cambiato il modo in cui sono sfruttate, il supporto
hardware e di comunicazione, l'uso da parte degli utenti.
Conoscere questi cambiamenti e il modo in cui le tecnologie sono state sviluppate e influenzate dal contesto aiuta a
comprenderle meglio e metterle in relazione.
URI
URI (Uniform Resource Identifier), che nasce indipendentemente da http, viene usato anche da altri protocolli. Sono una
sintassi usata in WWW per definire i nomi e gli indirizzi delle risorse. È indipendente dal protocollo.
Sono stati fattore determinante per il successo del WWW: attraverso gli URI, il WWW è stato in grado di identificare
risorse accessibili tramite il proprio protocollo, HTTP, e tramite tutti gli altri protocolli esistenti (FTP, Telnet, ecc.)→ punto
principale a cui gli altri sistemi non erano arrivati era una sintassi universale, indipendente dal protocollo e facilmente
memorizzabile (o quasi) con cui identificare le risorse di rete.
URI divisi in 2 sottogruppi:
1. URL = sintassi che contiene informazioni immediatamente utilizzabili per accedere alla risorsa (ad esempio, il
suo indirizzo di rete).
4
Li usiamo in ambito web: permette al server di recuperare file in questione. L = locator quindi per recuperare la
risorsa, non necessariamente si trova in quella posizione ma server ha tutte le info per recuperarla. Se risorsa viene
spostata quell’URL non è più valido.
2. URN = sintassi che permette una etichettatura permanente e non ripudiabile della risorsa, indipendentemente
dal riportare informazioni sull'accesso. Necessario quindi un meccanismo di traduzione verso gli URL.
Sintassi sovrapposta ma focus è sulla non ripudiabilità ovvero assegnare nome ad una risorsa che può cambiare
posizione ma non nome. Quindi sono pensati per essere permanenti.
5
• schema : [// authority] path [? query] [# fragment]
→La parte query individua un’ulteriore specificazione della risorsa all’interno dello spazio di nomi identificato dallo
schema e dall’URI precedente.
Di solito questi sono parametri passati all’URI (un processo) per specificare un risultato dinamico (es. l’output di una
query su un motore di ricerca).
Tipicamente ha la forma nome1=valore1&nome2=valore+in+molte+parole.
• schema : [// authority] path [? query] [# fragment]
→La parte fragment individua una risorsa secondaria (una risorsa associata, dipendente o in molti casi un frammento)
della risorsa primaria. Fragment permette di recuperare un frammento all’interno di una risorsa, quindi è risorsa
necessaria associata alla precedente, non necessariamente è una parte della risorsa precedente.
È tutta la parte che sta dopo al carattere di hash “#”.
Usata ad esempio per identificare sezioni all'interno di una pagina HTML.
6
ROUTING E URL ASSOLUTI E RELATIVI
Un SERVER WEB è un software in grado di gestire richieste http. È in ascolto su una porta TCP/IP (di default 80).
La richiesta indica una risorsa tramite un URL e usa quindi lo schema HTTP o HTTPS.
Una ROUTE è un'associazione della parte path di un URI ad una risorsa gestita o restituita da un server web.
MANAGED ROUTE: il server associa ogni URI ad una risorsa o attraverso il file system locale (risorse statiche) oppure
generate attraverso una computazione (risorse dinamiche). Molto di moda oggi con node.js e express.js.
Managed route→ Applicazione stessa si occupa della traduzione.
Permettono di fare mapping tra url e file vero e proprio: dalla ricerca, attraverso il calcolo ottiene un risultato
FILE SYSTEM ROUTE → il server associa la radice della parte path ad una directory del file system locale e ogni
filename valido all'interno di quella directory genera un URI corretto e funzionante. Il vecchio approccio via web server
come Apache.
Un URI ASSOLUTO contiene tutte le parti predefinite dal suo schema, esplicitamente precisate. Esempio: un’uri che
inizia con http.
Un URI GERARCHICO può però anche essere RELATIVO, (URI RELATIVI detto tecnicamente un URI
REFERENCE) usate in altre risorse che al loro interno contengono altri uri. In questo caso riportare solo una parte
dell'URI assoluto corrispondente "tagliando progressivamente parti da sinistra".
Partendo dall’uri relativo voglio sapere l’uri assoluto.
Un URI REFERENCE fa sempre riferimento ad un URI di base (ad esempio, l'URI assoluto del documento ospitante
l'URI reference) rispetto al quale fornisce porzioni differenti.
Esempio: l'URL reference pippo.html posto dentro al documento di URI http://www.sito.com/dir1/dir2/pluto.html fa
riferimento al documento il cui URI assoluto è http://www.sito.com/dir1/dir2/pippo.html
Parto da uri assoluto, che è il contenitore da cui è stato calcolato uri relativo e parto a scrivere in base a com’è scritto uri
relativo.
Risolvere un URI relativo significa identificare l'URI assoluto cercato sulla base dell'URI.
MIME
7
I SERVIZI MIME
DICHIARAZIONE DI TIPO
Tutti i messaggi MIME vengono identificati da un Content Type, che definisce il tipo di dati del messaggio e aiuta
l’applicazione ricevente a gestire il messaggio e a invocare l’applicazione più adatta.
N.B.: l’attribuzione dell’applicazione non viene fatta sulla base dell’estensione del nome del file.
MESSAGGI MULTI-TIPO
Un messaggio MIME può contenere parti di tipo diverso (es. un messaggio di tipo testo e un attachment binario).
In questo caso si creano dei sottomessaggi MIME per ciascuna parte (con il suo bravo content-type) e il messaggio
MIME complessivo diventa “multi-parte”, qualificando e codificando in maniera diversa ciascuna sottoparte.
• CONTENT-TYPE: il tipo MIME del contenuto. Serve per permettere al ricevente di scegliere il meccanismo più
adatto per presentare i dati. Specifica la natura del dato tramite la specificazione di tipo, sottotipo e ulteriori
parametri utili. Content-Type: text/plain; charset=ISO-8859-1
• CONTENT-TRANSFER-ENCODING: il tipo di codifica utilizzata per trasmettere i dati. Serve per la trasmissione su
canale SMTP di dati che non sono naturalmente corretti secondo le regole di SMTP: 7bit, sequenze CRLF ogni 1000
caratteri o meno. Sono valori accettabili “7bit” (default), “8bit”, “binary”, “quoted printable”, “base64” o altre
stringhe definite nel registro IANA
Content-Transfer-Encoding: base64
MIME - BASE 64
BASE 64 è un tipo di transfer encoding MIME suggerito per dati binari o multi-byte.
Viene identificato un sottoinsieme di 64 caratteri di US-ASCII sicuri, che hanno la stessa codifica in tutte le versioni di ISO
646. Questi sono:
- lettere maiuscole (26, 'A' => 0)
- lettere minuscole (26, 'a' => 26)
- numeri (10, '0' => 52)
- caratteri '+' e '/' (=> 62 e 63 rispettivamente).
Ogni flusso di dati viene suddiviso in blocchi di 24 bit (3 byte). A loro volta questi 24 bit sono suddivisi in 4 blocchi di 6 bit
ciascuno e codificati secondo una tabella prefissata in uno dei 64 caratteri già descritti.
Base64 NON È una tecnica crittografica!!
8
RUOLI IN HTTP
• CLIENT: un’applicazione che stabilisce una connessione HTTP, con lo scopo
di mandare richieste.
• SERVER: un’applicazione che accetta connessioni HTTP, e genera risposte.
• USER AGENT: client che inizia una richiesta HTTP (tipicamente un browser,
ma può anche essere un bot). Client che attiva connessione.
• ORIGIN SERVER: il server che possiede fisicamente la risorsa richiesta (è
l’ultimo della catena)
• PROXY: Un’applicazione intermediaria che agisce sia da client che da server. Le richieste sono soddisfatte
autonomamente o con possibili trasformazioni o controlli.
• GATEWAY: un’applicazione che agisce da intermediario per qualche altro server. A differenza della comunicazione
con il proxy, un client può non essere al corrente che si tratta del gateway.
Ruolo fondamentale in http è ruolo degli INTERMEDIARI = entità che ricevono richieste da uno e le inoltrano ad un altro
che responsabile della risorsa che poi la invia al proxy e poi lui la invia al richiedente.
Intermediari possono essere di tipo PROXY o GATEWAY
➢ PROXY è selezionato dal client o comunque la presenza del proxy è nota e riceve richiesta per girarla al server.
➢ GATEWAY interviene come se fosse ORIGIN SERVER quindi in modo trasparente rispetto a chi ha fatto la
richiesta.
CONNESSIONE HTTP
Una connessione HTTP è composta da una serie di richieste ed una serie corrispondente di risposte.
Le connessioni sono persistenti con:
• PIPELINING: trasmissione di più richieste senza attendere l'arrivo della risposta alle richieste precedenti. MA le
risposte sono restituite nello stesso ordine delle richieste.
• MULTIPLEXING: nella stessa connessione è possibile avere richieste e risposte multiple, restituite anche in ordine
diverso rispetto alle richieste e “ricostruite” nel client.
HTTP/2 ha introdotto molte novità per migliorare le performance, tra cui:
- Operazioni PUSH: il server anticipa le richieste successive del client
- Compressione degli header: i dati non sono trasmessi in chiaro ma
compressi (e in parallelo)
Non pipeline→ un’ulteriore richiesta può essere inviata solo dopo che sia
arrivata la risposta alla richiesta precedente
Pipeline → possono essere inviate altre richieste anche prima che arrivi la risposta alla richiesta precedente
Multiplexed → risposte possono arrivare in ordine diverso rispetto all’ordine con cui sono state inviate
RISORSE HTTP
HTTP →Protocollo per scambiarsi risorse ognuna identificata da URI.
Separa nettamente le risorse dalla loro rappresentazione e fornisce meccanismi di negoziazione del formato di dati, cioè
la possibilità di richiedere e ricevere (la rappresentazione di) una stessa risorsa in formati diversi.
HTTP implementa inoltre sofisticate politiche di caching che permettono di
memorizzare copie delle risorse sui server (proxy, gateway, etc.) coinvolti nella
trasmissione e controllare in modo accurata la validità di queste copie.
Un uso corretto di questi meccanismi migliora notevolmente le performance
delle applicazioni.
HTTP è gestito con coppia di richiesta-risposta.
Richiesta può partire da CLIENT o INTERMEDIARIO.
La risposta è generata o da ORIGIN SERVER (entità che detiene risorsa che mi interessa) o da INTERMEDIARIO.
9
RICHIESTA HTTP
La richiesta HTTP si compone di:
• Method: azione del server richiesta dal client
• URI: identificativo della risorsa locale al server
• Version: numero di versione di HTTP
• Header sono linee divise in:
- header generali
- header di entità
- header di richiesta
• Body è un messaggio MIME
METODI DI HTTP
I metodi (o verbi) di http indicano azione che viene eseguita sugli URI
I metodi indicano l'azione che il client richiede al server sulla risorsa, o meglio sulla rappresentazione della risorsa o,
ancora meglio, sulla copia della rappresentazione della risorsa
Chiamati anche verbi HTTP per evidenziare l'idea che esprimono azioni da eseguire sulle risorse, identificate a loro volta
da nomi (URI)
Un uso corretto dei metodi HTTP aiuta a creare applicazioni interoperabili e in grado di sfruttare al meglio i meccanismi di
caching di HTTP
I metodi principali: GET, HEAD, POST, PUT, DELETE, OPTIONS, PATCH
Guardiamo esempi dei più usati, GET e POST, e poi torneremo sui metodi a fine lezione visto la loro importanza per REST
- GET è il metodo più frequente, ed è quello che viene attivato facendo click su un link ipertestuale di un documento
HTML, o specificando un URL nell’apposito campo di un browser.
GET /courses/tw.html
GET /students/123456/exams/
- Il metodo POST serve per trasmettere informazioni dal client al server relative alla risorsa identificata nell'URI
POST /courses/1678
{
"titolo":"Tecnologie Web",
"descrizione":"Il corso..bla..bla.."
}
RISPOSTA HTTP
La risposta HTTP si compone di:
• Status code: identifica stato della richiesta per indicare se la richiesta è andata a
buon fine o meno.
• Version: numero di versione di HTTP
• Header: come per la richiesta:
- header generali
- header di entità
- header di risposta
• Body è un messaggio MIME
Lo Status code è un numero di tre cifre, di cui la prima indica la classe della risposta, e le altre due la risposta specifica.
Esistono le seguenti classi:
- 1xx: Informational→ Utilizzato per una risposta temporanea alla richiesta, durante il suo svolgimento. Server ha tutte
info per risposta ma deve processarle quindi invia richiesta intermedia per indicare che ci sta lavorando.
- 2xx: Successful. Il server ha ricevuto, capito e accettato la richiesta.
10
- 3xx: Redirection. La richiesta è corretta, ma sono necessarie altre azioni da parte del client per portare a termine la
richiesta. Server non ha tutte info per portare a termine richiesta e quindi sta richiedendo altre info al client.
- 4xx: Client error. La richiesta del client non può essere soddisfatta per un errore da parte del client (errore sintattico
o richiesta non autorizzata).
- 5xx: Server error. La richiesta può anche essere corretta, ma il server non riesce a soddisfarla per un problema
interno.
Status code appartengono ad http non all’applicazione. Esplicitare i codici significa dire agli intermediari qual è il vero
errore nella richiesta.
L'uso corretto degli status code aiuta a costruire API chiare e più semplici da usare.
Il client non ha necessità di leggere il body della risposta ma già dallo status code può capire se la richiesta è andata a
buon fine–Può trovare dettagli nel body ma la dipendenza con il server è ridotta.
Permette a tutte le entità coinvolte nella comunicazione di capire meglio cosa succede, e sfruttare i meccanismi di
caching e redirezione di http.
Migliora uniformità e interoperabilità.
Importanti sapere codici HTTP (esempi di status code) da sapere per l’esame
• 100 Continue (se il client non ha ancora mandato il body)
• 200 Ok (GET con successo)
• 201 Created (PUT con successo)
• 301 Moved permanently (URL non valida, il server conosce la nuova posizione)
• 400 Bad request (errore sintattico nella richiesta)
• 401 Unauthorized (manca l’autorizzazione)
• 403 Forbidden (richiesta non autorizzabile)
• 404 Not found (URL errato)
• 500 Internal server error (tipicamente un errore nel codice server-side)
Gli Header sono righe di testo (RFC822) che specificano informazioni
aggiuntive • Sono presenti sia nelle richieste che nelle risposte e ne
descrivono diversi aspetti.
Header generali → si applicano solo al messaggio trasmesso e si
applicano sia ad una richiesta che ad una risposta, ma non
necessariamente alla risorsa trasmessa.
Esempi:
- Date: data ed ora della trasmissione
- Transfer-Encoding: il tipo di formato di codifica usato per la trasmissione
- Cache-Control: il tipo di meccanismo di caching richiesto o suggerito per la risorsa
- Connection: il tipo di connessione da usare (tenere attiva, chiudere dopo la risposta, ecc.)
Header dell’entità → danno informazioni sul body del messaggio, o, se non vi è body, sulla risorsa specificata.
Esempi:
- Content-Type: il tipo MIME dell’entità nel body. Questo header è obbligatorio in ogni messaggio che abbia un body.
- Content-Length: la lunghezza in byte del body. Obbligatorio, soprattutto se la connessione è persistente.
- Content-Encoding, Content-Language, Content-Location, Content-MD5, Content-Range: la codifica, il linguaggio,
l’URL della risorsa specifica, il valore di digest MD5 e il range richiesto della risorsa.
Header della richiesta →sono posti dal client per specificare informazioni sulla richiesta e su se stesso al server.
Esempi:
- User-Agent: una stringa che descrive il client che origina la richiesta; tipo, versione e sistema operativo del client,
tipicamente.
- Referer: l’URL della pagina mostrata all’utente mentre richiede il nuovo URL.
- Host: il nome di dominio e la porta a cui viene fatta la connessione.
Altri header della richiesta sono usati per gestire la cache e i meccanismi di autenticazione.
11
Header della risposta → sono posti dal server per specificare informazioni sulla risposta e su se stesso al client.
Esempi:
- Server: una stringa che descrive il server: tipo, sistema operativo e versione.
- WWW-Authenticate: challenge utilizzata per i meccanismi di autenticazione
IMPORTANZA DEL CONTENT-TYPE
Tra gli Header della risposta sono particolarmente utili quelli che definiscono il tipo di dato contenuto nella risposta.
Queste informazioni permettono al client di processare correttamente la (rappresentazione di una) risorsa.
Se viene fornita un'entità in risposta, infatti, gli header Content-type e Content-length sono obbligatori.
È solo grazie al content type che lo user agent sa come visualizzare l'oggetto ricevuto
È solo grazie al content length che lo user agent sa che ha ricevuto tutto l'oggetto richiesto.
METODI HTTP
Due proprietà importanti:
1. SICUREZZA (niente a che vedere con password, hacking e privacy) →un metodo è sicuro se non genera
cambiamenti allo stato interno del server (a parte ovviamente nei log). –Un metodo sicuro può essere eseguito da un
nodo intermedio (es. una cache) senza effetti negativi.
2. IDEMPOTENZA: un metodo è idempotente se l’effetto sul server di più richieste identiche è lo stesso di quello di
una sola richiesta (a parte ovviamente i log). Un metodo idempotente può essere ri-eseguito da più agenti o in più
tempi diversi senza effetti negativi.
• Il METODO GET → più importante (ed unico in v. 0.9) metodo di HTTP è GET, che richiede una risorsa ad un server.
Questo è il metodo più frequente, ed è quello che viene attivato facendo click su un link ipertestuale di un documento
HTML, o specificando un URL nell’apposito campo di un browser.
→GET è SICURO ed IDEMPOTENTE
GET /courses/tw.html
GET /students/123456
GET /students/123456/exams/
• Il METODO HEAD →è simile al metodo GET, ma il server deve rispondere soltanto con gli header relativi, senza il corpo.
Viene usato per verificare validità, accessibilità e coerenza in cache di un URI
→HEAD è SICURO ed IDEMPOTENTE
HEAD /courses/tw.html
• Il METODO POST serve per trasmettere informazioni dal client al server relative alla risorsa identificata nell'URI.
Può essere usato anche per creare nuove risorse.
Viene usato per esempio per spedire i dati di un form HTML ad un’applicazione server-side
→POST non è sicuro né idempotente
POST /courses/1678
{
"titolo":"Tecnologie Web",
"descrizione":"Il corso..bla..bla.."
}
• Il METODO PUT serve per trasmettere delle informazioni dal client al server, creando o sostituendo la risorsa
specificata. In generale, l’argomento del metodo PUT è la risorsa che ci si aspetta di ottenere facendo un GET in seguito
con lo stesso nome.
Non offre garanzie di controllo degli accessi o locking
→PUT è IDEMPOTENTE ma non sicuro
PUT /courses/1678
{
"id":1678,
"titolo":"Tecnologie Web",
}
12
• Il METODO DELETE serve per rimuovere le informazioni connesse con una risorsa.
Dopo l’esecuzione di un DELETE, la risorsa non esiste più e ogni successiva richiesta di GET risulterà in un errore 404 Not
Found.
Il metodo DELETE su una risorsa già non esistente è lecito e non genera un errore.
→DELETE è IDEMPOTENTE e non sicuro
DELETE /courses/1678
• Il METODO PATCH è usato per aggiornare parzialmente la risorsa identificata dall'URI.
Usato per indicare quindi modifiche incrementali e non sovrascrivere risorse al server, come ad esempio nel caso di PUT.
Indica quindi le modifiche da effettuare su una risorsa esistente.
→PATCH non è sicuro né idempotente
PATCH /courses/1678 { "op" : "update" "cfu":"6" }
• Il METODO OPTIONS viene usato per verificare opzioni, requisiti e servizi di un server, senza implicare che seguirà poi
una altra richiesta.
Usato per il problema del cross-site scripting: CORS, ci torneremo parlando di AJAX.
API REST
API Web
Un API Web descrive un'interfaccia HTTP che permette ad applicazioni remote di utilizzare i servizi di dell'applicazione.
Queste possono essere:
- Applicazioni automatiche che utilizzano i dati dell'applicazione
- Applicazioni Web che mostrano all'utente un menù di opzioni, magari anche un form, e gli permettono di eseguire
un'azione sui dati dell'applicazione
REST
REST è l’acronimo di REpresentional State Transfer, ed è il modello architetturale che sta dietro al World Wide Web e in
generale dietro alle applicazioni web “ben fatte” secondo i progettisti di HTTP.
REST è un modo per progettare API per sfruttare caratteristiche di http.
Applicazioni non REST si basano sulla generazione di un API che specifica le funzioni messe a disposizione
dell’applicazione, e alla creazione di un’interfaccia indipendente dal protocollo di trasporto e ad essa completamente
nascosta.
Viceversa, un’applicazione REST si basa fondamentalmente sull’uso dei protocolli di trasporto (HTTP) e di naming (URI)
per generare interfacce generiche di interazione con l’applicazione, e fortemente connesse con l’ambiente d’uso.
L’obiettivo è creare API consistenti, predicibili e facili da capire e usare.
IL MODELLO CRUD
CRUD è un pattern tipico delle applicazioni di trattamento dei dati.
Ipotizza che tutte le operazioni sui dati siano una di:
- CREATE (inserimento nel database di un nuovo record)
Crea un cliente il cui nome è "Rossi SpA", il telefono "051 654321", la città "Bologna" e restituisce il codice
identificatore che è 4123.
13
- READ (accesso in lettura al database)
individuale: dammi la scheda del cliente con id=4123,
contenitore: dammi la lista dei clienti la cui proprietà città è uguale al valore "Bologna"
- UPDATE
Cambia il numero di telefono del cliente il cui id=4123 in "051 123456"
- DELETE
Rimuovi dal database il cliente con id=4123
In ambito web tutto è identificato da un URI quindi decidiamo quali sono le risorse significative per l’applicazione e come
sono fatti gli URI che identificano queste risorse.
ARCHITETTURA REST
L’architettura REST si basa su 4 punti :
1. Definire risorsa ogni concetto rilevante dell’applicazione Web
2. Associargli un URI come l’identificatore e selettore primario
3. Usare i verbi HTTP per esprimere ogni operazione dell’applicazione secondo il modello CRUD:
- creazione di un nuovo oggetto (metodo PUT)
- visualizzazione dello stato della risorsa (metodo GET)
- cambio di stato della risorsa (metodo POST)
- cancellazione di una risorsa (metodo DELETE)
→ Le operazioni che posso fare con queste risorse le definisco con i metodi di HTTP
4. Esprimere in maniera parametrica ogni rappresentazione dello stato interno della risorsa, personalizzabile dal
richiedente attraverso un Content Type preciso.
INDIVIDUI E COLLEZIONI
REST identifica due concetti fondamentali: INDIVIDUI e COLLEZIONI
- un cliente vs. l'insieme di tutti i clienti
- un esame vs. l'insieme di tutti gli esami superati
Fornisce URI ad entrambi.
Ogni operazione avviene su uno e uno solo di questi concetti.
Su entrambi si possono eseguire operazioni CRUD. A seconda della combinazione di verbi e risorse otteniamo l'insieme
delle operazioni possibili.
Ciò che passa come corpo di una richiesta e/o risposta NON è la risorsa, ma una rappresentazione della risorsa, di cui gli
attori si servono per portare a termine l'operazione.
Identificare individui nell’applicazione e collezioni di individui, una volta fatto ho descritto ciò che è possibile fare
nell’applicazione, se non c’è URI di quella richiesta significa che non è un’operazione permessa.
GERARCHIE
Le collezioni possono "contenere" individui o altre collezioni
Utilizzo di gerarchie permette di strutturare /organizzare individui in collezioni e le collezioni in altre collezioni, quindi
posso ragionare in termini gerarchici.
È consigliabile strutturare gli URI in modo gerarchico, per esplicitare queste relazioni
API più leggibile e routing semplificato in molti framework di sviluppo.
Ad esempio:
- Tutti i clienti /clients/
- Il cliente 1234 /clients/1234
- Tutti gli ordini del cliente 1234 /clients/1234/orders/
14
LINEE GUIDA DEGLI URI IN REST
Un filtro genera un sottoinsieme specificato attraverso una regola di qualche tipo. La gerarchia permette di specificare i
tipi più frequenti e rilevanti di filtro. Altrimenti si usa la parte query dell'URI di una collezione
Una API è RESTful se utilizza i principi REST nel fornire accesso ai servizi che offre.
CONCLUSIONI
REST considera ogni applicazione come un ambiente di cui si cambia lo stato attraverso un insieme limitato di comandi (i
metodi HTTP) applicati alle risorse (espresse attraverso URI) e visualizzate attraverso una esplicita richiesta di
rappresentazione (attraverso un content Type MIME).
REST ha il pregio di sfruttare completamente ed esattamente tutti gli artifici del web, ed in particolare caching, proxying,
sicurezza, ecc.
Inoltre l'aprirsi all'uso sistematico di URI permette ad applicazioni sofisticate basate su logica ed inferenza si sfruttare le
tecniche del Semantic Web per creare funzionalità ancora più sofisticate e intelligenti con applicazioni create su
architettura REST
15
OPENAPI
OPENAPI linguaggio che può avere diverse sintassi che descrive api web e descrive tutti gli elementi che la caratterizza.
Con openAPI possiamo descrivere quali sono uri con cui andiamo a lavorare e i verbi ovvero le operazioni possibili
nell’applicazione, descrivere quali sono gli header per esempio i formati. All’interno degli uri posso poter specificare dei
parametri.
Altra cosa che vogliamo è gestire i messaggi di errore: cosa mi aspetto di usare per gestire messaggi di errore? Qual è
pezzo di http che dice se risposta è andata a buon fine? Lo stato, quindi dovrò gestire lo stato.
URI è strumento per indicare dove server risponde.
Queste info sono descritte con linguaggio openAPI (non interessa storia di open API)
Avere API in modo processato è negli interessi di tutti.
YAML
YAML →Sintassi testuale che permette di descrivere dati strutturati,
deriva da Python, permette di descrivere oggetti, proprietà di oggetti
Utilizza indentazione per indicare gerarchia → indentazione come
modello di annidamento.
SEZIONE PATHS
La parte centrale di un'API descrive i percorsi (URL) corrispondenti alle
operazioni possibili sull'API.
Seguono la struttura: <host>/<basePath>/<path>
Per ogni percorso (path o endpoint) si definiscono tutte le possibili
operazioni che, secondo i princìpi REST, sono identificate dal metodo
HTTP corrispondente.
Per ogni path quindi ci sono tante sottosezioni quante sono le
operazioni e per ognuna:
- Informazioni generali
- Parametri di input e di output.
PARAMETRI IN INPUT
I parametri in input sono descritti nella sezione parameters e per ogni
parametro è possibile definire:
- tipo del parametro: keyword in che può assumere valori path,
query o body
- nome (name) e descrizione (description)
- se è opzionale o obbligatorio (required)
- formato del/i valore/i che il dato può assumere (schema). Il tipo può essere scalare (interi, stringhe, date, ecc.), o un
oggetto o un vettore di valori scalari o oggetti.
16
OGGETTI E DEFINIZIONI
Nell'esempio precedente il body contiene un oggetto di tipo User; viene infatti passata un'intera risorsa (o meglio la sua
rappresentazione) come parametro.
La sezione definitions permette di definire i tipi degli oggetti, le loro proprietà e possibili valori.
Questi tipi possono essere referenziati (tramite schema -> $ref) sia nelle richieste che nelle risposte.
OUTPUT
L'output (dati e codici e messaggi di errore) sono definiti attraverso la keyword responses. Si specifica il tipo di output
atteso nel body della risposta. Inoltre ogni risposta ha un id numerico univoco, associato al codice HTTP corrispondente:
- 200 viene usato per indicare che non c’è stato alcun errore
- da 400 in su vengono in genere usati per indicare messaggi di errore
Prima di visualizzare ed elaboratore contenuti e dati Web, si pone il problema di rappresentarli all'interno di un
calcolatore e trasferirli da un calcolatore all'altro.
Il calcolatore infatti usa una rappresentazione numerica dell'informazione e in particolare la codifica binaria, basata su
due simboli 0 e 1 (bit).
Per rappresentare un dato non numerico abbiamo quindi la necessità di trasformarlo in una sequenza di numeri
memorizzabili nel calcolatore.
Questo processo di digitalizzazione varia a seconda del dato che vogliamo rappresentare. Noi guardiamo testi e colori ma
ragionamenti simili si applicano a suoni e video.
17
I valori in binario si iniziano con 0b e quelli in esadecimale con 0x.
Quanti simboli?
• k bit => 2k stati => 2k simboli/oggetti
• Ricapitolando:
- 1 bit => 2 valori (0, 1)
- 2 bit => 22 valori (00, 01, 10, 11)
- 7 bit => 27 valori => 128 valori
- 8 bit (1 byte) => 28 valori => 256 valori
- 16 bit (2 byte) => 216 valori => 65536 valori
- 32 bit (4 byte) => 232 valori => 4.294.967.296 valori
Per codificare un testo si traduce ogni carattere in un valore numerico, rappresentato poi in notazione binaria o
esadecimale, e si concatenano i valori numerici ottenuti.
Deve essere evidente e non ambiguo il criterio di associazione di un blocco di bit ad un carattere dell'alfabeto e il
meccanismo di traduzione.
Alcuni standard proposti:
ASCII (American Standard Code for Information Interchange)→ definisce valori per 128 caratteri, ovvero 7 bit su 8. Nello
standard originale il primo bit non è significativo ed è pensato come bit di parità.
ASCII possiede 33 caratteri (0-31 e 127) di controllo, inclusi alcuni ormai non più rilevanti. Codifica anche spazi e "andata
a capo" (CR e LF)–Gli altri 95 sono caratteri dell'alfabeto inglese, maiuscole e minuscole, numeri e punteggiatura.
ISO 8859/1 (ISO Latin 1)→ comprende un certo numero di caratteri degli alfabeti europei come accenti, ecc.
Diverse estensioni di ASCII sono state proposte per utilizzare il primo bit e accedere a tutti i 256 caratteri. Nessuna di
queste è standard tranne ISO Latin 1.
ISO Latin 1 è usato automaticamente da HTTP e alcuni sistemi operativi. Ovviamente ISO Latin 1 è compatibile all’indietro
con ASCII, di cui è un estensione per i soli caratteri >127.
UCS e UTF→ Si è cercato di definire a uno standard unico in grado di coprire tutti gli alfabeti che quindi usa un numero
maggiore di byte.
Due grandi famiglie di schemi:
- a lunghezza fissa:
• UCS-2 (2 byte) → è uno schema a due byte ed è un’estensione di ISO Latin 1
• UCS-4 (4 byte) → è uno schema a 31 bit in 4 byte, estensione di UCS-2
Si usa sempre lo stesso numero di byte per ogni carattere (due o quattro se UCS-2 o UCS-4)
- a lunghezza variabile: UTF-8, UTF-16 e UTF-32
UTF nasce dall'osservazione che i testi nella maggior parte dei casi sono scritti in un unico alfabeto o in alfabeti vicini
→quindi è uno spreco usare 2 o 4 byte per ogni carattere, anche quando sarebbe sufficiente usare 1 byte.
UTF è un sistema a lunghezza variabile che permette di accedere a tutti i caratteri definiti di UCS-4:
o I codici compresi tra 0 - 127 (ASCII a 7 bit) richiedono 1 byte
o I codici derivati dall'alfabeto latino e tutti gli script non-ideografici richiedono 2 byte
o I codici ideografici (orientali) richiedono 3 byte
o Tutti gli altri 4 byte.
Bit iniziali e di controllo permettono di capire come interpretare la restante seguenza di bit (quanti byte considerare)
18
CODIFICA COLORI
Come codificare i colori? L'occhio percepisce i colori attraverso tre tipi di coni, che contengono pigmenti sensibili a
diverse lunghezze d'onda.
Lo spettro complessivo dei colori riconoscibili dall'occhio umano può essere espresso come uno spazio lineare di valori
organizzati su un numero di dimensioni comode (3 o 4).
SINTESI ADDITIVA →In uno SPAZIO COLORE ADDITIVO, ogni colore è definito come la somma del contributo di tre
o quattro colori primari. Nero è definito come l'assenza di contributi, poi i colori diventano via via più chiari e brillanti tanto
maggiore è il contributo di ciascuna componente. Il bianco è definito come il massimo contributo possibile di tutte le
componenti. I device ad emissione di luce, come gli schermi dei computer o i proiettori, definiscono i colori usando un
modello additivo. Gli stimoli arrivano nell'occhio simultaneamente e in rapida successione e fanno percepire il colore.
RGB è uno spazio colore additivo basato sull'identificazione di Rosso, Verde e Blu come colori primari. Il colore è
espresso con 3 valori. Con 1 byte per colore (RGB24), si avranno quindi 256 valori per ogni colore prima (esprimibili in
notazione decimale, binaria ed esadecimale).
RGBa è uno spazio colore derivato dav RGB in cui viene aggiunta una quarta dimensione, chiamata canale alpha che
esprime come percentuale 0-100% l'opacità.
SINTESI SOTTRATTIVA → In uno SPAZIO COLORE SOTTRATTIVO , ogni colore è definito come lo spettro residuo
della luce ambientale riflessa da una composizione di pigmenti di colori primari che bloccano (sottraggono) parzialmente
tale riflesso. Bianco è definito come l'assenza di contributi (cioè è il colore della superficie riflettente senza pigmenti) e il
nero è il colore raggiunto coprendo completamente la sorgente riflettente con pigmenti.
Lo spazio colore sottrattiva più usato si chiama CMY (Cyan – Magenta – Yellow)→ è uno spazio colore sottrattivo basato
sull'identificazione di quattro colori primari, Cyan, Giallo, Magenta e Key (che è un nero molto scuro). CYMK usa quattro
colori invece di tre perché l'inchiostro nero fornisce una definizione dei colori molto migliore, aumentando il contrasto e
riducendo la quantità di inchiostro colorato necessario per le tinte più scure.
Il sorgente delle pagine Web è in HTML (HyperText Markup Language), un linguaggio che “marca”:
- struttura del documento
- informazioni di presentazione
- collegamenti ipertestuali (e URL della destinazione)
- risorse multimediali (e URL)
→Il browser è in grado di interpretare queste informazioni e visualizzare la pagina finale.
MARKUP = ogni mezzo per rendere esplicita una particolare interpretazione di un testo. Rende testo più leggibile e
permette di specificare ulteriori usi del testo.
Esistono diversi tipi di markup tra cui:
• PRESENTAZIONALE: indica effetti (grafici o altro) per rendere più chiara la presentazione del contenuto.
• PROCEDURALE: indica ad un sistema automatico che che procedura (serie di istruzioni) eseguire per visualizzare il
contenuto.
• DESCRITTIVO: individua strutturalmente il tipo di ogni elemento del contenuto e ne evidenzia il ruolo.
• REFERENZIALE: consiste nel fare riferimento ad entità esterne al documento per fornire significato o effetto grafico
ad elementi del document.
META-LINGUAGGIO = è un linguaggio per definire linguaggi, una grammatica di costruzione di linguaggi.
SGML e XML non sono linguaggi di markup, ma linguaggi con cui definiamo linguaggi di markup, appunto metalinguaggi di
markup →SGML e XML non sanno cos’è un paragrafo, una lista, un titolo, ma forniscono grammatiche che ci permettono
di definirli.
19
→HTML nasce come LINGUAGGIO DI MARKUP definito usando la grammatica SGML.
Il markup in SGML è :
• strutturato: possibile definire una serie di regole affinché il testo sia considerabile strutturalmente corretto
• gerarchico: gli elementi del testo possono essere annidati e specificare la struttura in maniera gerarchica
Un documento con markup di derivazione SGML, inclusi HTML e XML, contiene:
- ELEMENTI→ parti di documento dotate di un senso proprio, e sono individuati da tag iniziale, contenuto e tag finale
(non confondere i tag con gli elementi), ATTRIBUTI → o informazioni aggiuntive sugli elementi, tipicamente espressi
in sintassi nome="valore" e TESTO → contenuto vero è proprio. Viene anche detto #PCDATA, Parsed Character
DATA, perché è processato ("parsato") per sostituire le entità.
- ENTITÀ→ frammenti di documento memorizzati separatamente e richiamabili all’interno del documento.
- COMMENTI (ignorati dalle applicazioni di rendering) e PROCESSING INSTRUCTIONS→ elementi particolari usati
per dare indicazioni alle applicazioni (molto usate in XML, poco in HTML).
XML
→è una raccomandazione W3C del 10 febbraio 1998 definita come un sottoinsieme di SGML ma è molto più formalizzata.
XML distingue due tipi di documenti rilevanti per le applicazioni:
- BEN FORMATO: se ha una struttura sufficientemente regolare e comprensibile da poter essere controllata.
Documento XML si dice ben formato se:
✓ Tutti i tag di apertura e chiusura corrispondono e sono ben annidati
✓ Esiste un elemento radice che contiene tutti gli altri
✓ Gli elementi vuoti (senza contenuto) utilizzano un simbolo speciale di fine tag: <vuoto/>
✓ Tutti gli attributi sono sempre racchiusi tra virgolette
✓ Tutte le entità sono definite
→Se un documento non rispetta queste regole NON può essere processato da un'applicazione XML
Questa rigidità garantisce maggiore controllo e interoperabilità tra le applicazioni
- un documento è VALIDO se presenta uno schema che ne definisce la struttura (chiamato DTD, Document Type
Definition come per SGML) ed è possibile validarlo usando questo DTD.
Se un documento è ben formato può essere rappresentato in memoria come un albero, chiamato DOM (Document
Object Model) = è un’interfaccia di programmazione (API) per documenti sia XML che HTML. Definisce la struttura logica
dei documenti ed il modo in cui si accede e si manipola un documento.
Utilizzando DOM i programmatori possono costruire documenti, navigare attraverso la loro struttura, e aggiungere,
modificare o cancellare elementi.
Ogni componente di un documento XML (o HTML) può essere letto,
modificato, cancellato o aggiunto utilizzando il DOM.
L’oggetto principale di DOM è DOMNode, che però è una interfaccia (cioè
viene solo usata per crearne classi).
Il core del DOM definisce alcune classi fondamentali per i documenti
HTML e XML, e ne specifica proprietà e metodi.
Gli oggetti principali definiti nel DOM sono:
DOMNode specifica i metodi per accedere a tutti gli elementi di un nodo di un documento, inclusi il nodo radice, il nodo
documento, i nodi elemento, i nodi attributo, i nodi testo, ecc.
Le versioni di HTML hanno adottato in modo molto diverso le regole di buona forma e validazione, sotto le diverse spinte
del W3C e dei produttori di browser.
20
Esistono differenze anche sensibili tra un documento HTML corretto e un documento HTML visualizzabile da un browser
Web → Non è detto che un documento HTML “accettabile” sia “ben fatto”.
Il linguaggio HTML un tipo di documento SGML (esiste un DTD di HTML, anzi più di uno) progettato per marcare documenti
ipertestuali. HTML 4 è il linguaggio in cui è scritta la stragrande maggioranza delle pagine Web attuali.
Molte pagine HTML sono diventate “tag soup”, ossia un insieme di elementi non conformi allo standard→ I browser si
sono preoccupati poco della correttezza sintattica o strutturale dei documenti HTML.
Per gestire sia le pagine conformi allo standard che quelle non compatibili, sono stati introdotti due modelli di rendering:
QUIRKS MODE e STRICT MODE.
Se la pagina non specifica niente, il browser adotta il modo compatibile (QUIRKS MODE), altrimenti se l’autore lo
richiede esplicitamente attiva il modo restrittivo e corretto (STRICT MODE).
XHTML
XHTML 1.0 è una Recommendation W3C del 2000. È una riformulazione di HTML 4 come un’applicazione di XML.
→XHTML è il primo di una serie di DTD che riproducono, limitano ed estendono HTML. Sono fatti per lavorare con user
agent basati su XML, ma con un’esplicita strategia di transizione.
I documenti debbono essere ben formati, in particolare l’annidamento deve essere corretto.
XHTML 2.0 adotta solo sintassi XML, rimuove tutti gli elementi prestazionali, riduce l’interattività e non è compatibile
all’indietro →in pratica la proposta non ha successo e il WG chiude.
Nel 2004, Firefox e Opera proposero al W3C la riapertura del Working Group su HTML per lo sviluppo di nuove versioni del
linguaggio. La proposta, che ignorava volutamente XHTML e la rigida sintassi di XML, venne bocciata dal W3C.
Venne così creata una comunità aperta chiamata WHATWG (Web Hypertext Application Technology Working Group)
finanziata e supportata da Mozilla, Opera e Apple, che ha iniziato a lavorare ad una versione “intermedia” di HTML, “Web
Application 1.0” (WA1), meno ambiziosa di XHTML 2.0.
Nel 2007 il W3C dovette ammettere che queste modifiche avevano un impatto innegabile (“he who ships working code
wins”) riaprì il working group con tutti i membri del WHAT per creare una nuova versione del linguaggio, (X)HTML 5.
(X)HTML 5
WA1 accetta l’amara realtà dei browser odierni che dicono che non è mai esistita una grammatica SGML per HTML, ma
che il linguaggio è sempre stato
- O un’applicazione di XML (XHTML*)
- Oppure una tag soup in cui i browser accettano ogni sorta di “porcheria” e fanno il meglio che possono
WA1 è più interessato a mettere a posto le cose che certamente non vanno piuttosto che lavorare su un linguaggio
completamente nuovo. E il W3C deve adeguarsi.
Anche perché WA1 ha supporto dichiarato da tutti i browser e di tutta l’industria delle applicazioni Web.
“(X)HTML 5” diventa quindi solo “HTML 5” e successivamente solo “HTML”.
Il “nuovo” HTML è, per scelta del WG, una specifica perennemente in sviluppo (“living standard”)
Cambia completamente il modello di sviluppo del linguaggio che si allontana sensibilmente dall’approccio sistematico e
democratico (ma non privo di difetti) di evoluzione degli altri standard W3C.
È la vittoria indiscussa dei produttori di browser: sia per le nuove caratteristiche del linguaggio sia per il modo in cui è
sviluppato.
Esistono quindi versioni di HTML?
21
Nel Working Group di HTML convivono quindi due “anime” ma con scarsi risultati e nel 2011 i gruppi si dividono.
Lo sviluppo va avanti in parallello: il W3C continua a standardizzare "snapshot" di "HTML Living Standard" e a dargli
un'approvazione formale con "HTML 5.x".
Nel 2019 W3C e WHATCG raggiungono un accordo e si impegnano a sviluppare un'unica versione di HTML, nell'ottica di
Web come Open Platform.
HTML(5) semplifica e usa un unico DocType, da indicare all'inizio delle pagine prima dell'elemento radice:
In realtà dalla prospettiva WHATCG questi documenti non sono propriamente “mal formati” ma semplicemente “non
strict”. Sono validi a tutti gli effetti, tanto quanto i documenti XHTML!
Potremmo dire: “l’importante è arrivare ad una struttura dati in memoria unica su cui costruire applicazioni”.
È a questo scopo che la vera attenzione da parte del WHATWG è la costruzione di una struttura dati chiamata
DOCUMENT OBJECT MODEL (DOM), a cui sia possibile arrivare a partire dalla stringa HTML e da cui si possa generare
nuovamente una altra stringa HTML.
Un problema risolto?
Aver uniformato l’algoritmo di parsing non è un deterrente per creare pagine “ben formate”, al contrario lascia maggiore
libertà e margine di errore agli sviluppatori.
Più complesso estrarre dati e implementare manipolazioni automatiche dei contenuti, tranne ovviamente il caso il
sistema espone un'API di accesso ai dati.
La cosa si complica ancora con i sistemi a componenti (es. AngularJS o React): lo stesso concetto di markup perderà
valore a vantaggio di sintassi miste Javascript/Markup/CSS/whatever create ad hoc e mai standardizzate.
CONCLUSIONI
Esistono differenze anche sensibili tra un documento HTML sintatticamente corretto e un documento HTML visualizzabile
da un browser Web.
Anche se sintatticamente in buona forma un documento HTML può essere strutturato in modo non corretto.
Separare contenuto e struttura è fondamentale in quest’ottica …così come evidenziare il ruolo dei singoli elementi e
marcarli correttamente.
Importante usare correttamente gli elementi HTML e CSS.
22
HTML (HYPERTEXT MARKUP LANGUAGE)
PREMESSE
MAIUSCOLO/MINUSCOLO →HTML non è sensibile al
maiuscolo/minuscolo (XHTML lo è e vuole tutto in minuscolo).
ENTITÀ IN HTML
HTML definisce un certo numero di entità per quei caratteri che sono:
• proibiti perché usati in HTML (, &, “, ecc.)
• proibiti perché non presenti nell’ASCII a 7 bit.
Esempio:
23
ELEMENTI DI HTML
24
- <nav> →liste di navigazione: particolari sezioni dedicate a raggruppare link alla pagina corrente (o a sezioni di) o
ad altre pagine. Si usa spesso in combinazione con <header> e <footer>.
Le sezioni <nav> sono molto utili per l’accessibilità, in quanto possono essere più facilmente identificate e
accedute anche da utenti disabili (tramite screenreaders o altri ausili). Possono essere usate anche per
attivare/disattivare le funzionalità di navigazione in base allo user-agent (browser) che sta accedendo alla
pagina.
• ELEMENTI DI BLOCCO
I tag di BLOCCO definiscono l’esistenza di blocchi di testo che contengono ELEMENTI INLINE.
Elementi base:
- P (paragrafo)
- DIV (generico blocco)
- PRE (blocco preformattato)
- ADDRESS (indicazioni sull’autore della pagina)
- BLOCKQUOTE (citazione lunga)
Blocchi con ruolo strutturale: H1, H2, H3, H4, H5, H6 (intestazione di blocco)
• ELEMENTI DI LISTA
Le liste di elementi sono contenitori di elementi omogenei per tipo.
- UL: Lista a pallini di <LI>; Attributo type (disc, square, circle)
- OL: lista a numeri o lettere di <LI>; attributi start (valore iniziale) e type (1, a, A, i, I).
- DIR, MENU: liste compatte, poco usate
- DL: lista di definizioni <DT> (definition term) e <DD> (definition data)
• ELEMENTI INLINE (o di carattere) (B, I, SPAN, ecc.)→ non spezzano il blocco (non vanno a capo) e si includono
liberamente l’uno dentro all’altro. Non esistono vincoli di contenimento.
Si dividono in elementi fontstyle e elementi phrase.
I tag fontstyle forniscono informazioni specifiche di rendering. Molti sono deprecati e si suggerisce comunque
sempre di usare gli stili CSS.
- TT (TeleType, font monospaziato, ad es. Courier)
- I (corsivo)
- B grassetto
- U (sottolineato - deprecato)
- S e STRIKE (testo barrato - deprecato)
- BIG, SMALL (testo più grande e più piccolo)
- EM (enfasi)
- CITE (breve citazione)
- STRONG (enfasi maggiore)
- Q (citazione lunga)
- DFN (definizione)
- ABBR e ACRONYM (abbreviazioni ed acronimi)
- CODE (frammento di programma)
- SUP e SUB (testo in apice e in pedice)
- SAMP (output d’esempio)
- BDO (bidirectional override)
- KBD (testo inserito dall’utente)
- SPAN (generico elemento inline)
- VAR (variabile di programma)
• ELEMENTI SPECIALI (A, IMG, HR, BR)
LINK IPERTESTUALI (anchors)→I link sono definiti con elementi (àncore nel documento). È sintatticamente un
elemento INLINE. L'unica limitazione è che gli elementi non possono annidarsi.
Attributi:
- HREF: specifica l'URI della destinazione. Quindi <a href = “xxx”>…</a> è l'ancora di partenza di un link.
- NAME: specifica un nome che può essere usato come ancora di destinazione di un link.
Quindi <a name = “xxx”>…</a> è l'ancora finale di un link.
25
IMMAGINI → Le immagini INLINE sono definite attraverso l’elemento IMG. Formati tipici: JPEG, GIF, PNG.
FIGURE (Diverso da IMG che è un elemento inline)→ HTML5 ha introdotto elemento specifico per aggiungere
un'immagine ad un documento, corredata da una didascalia, in un unico blocco semanticamente rilevante.
• TABELLE (TABLE, TR, TD, TH)→ vengono specificate riga per riga. Di ogni riga si possono precisare gli elementi, che
sono o intestazioni o celle normali. Una tabella può anche avere una didascalia <caption>, un’intestazione
<thead> ed una sezione conclusiva <tfoot> (il corpo della tabella, quindi, sarà <tbody>). È possibile descrivere
insieme le caratteristiche visive delle colonne.
Le celle possono occupare più righe o più colonne. Si usano gli attributi @rowspan e @colspan per indicare il
numero di righe o colonne occupate dalla cella.
Elementi e attributi per tabelle:
TABLE: tabella→ @border, @cellpadding e @cellspacing per indicare bordi e spazi tra le celle e nelle celle
(deprecati, meglio usare CSS)
TR: riga
TD e TH: cella semplice o di intestazione→ @rowspan e @colspan per indicare celle che occupa più righe o colonne
THEAD, TBODY, TFOOT: raggruppano righe rispettivamente in intestazione, body e footer della tabella
CAPTION: didascalia
COLGROUP, COL: specificano proprietà di gruppi colonne
• FORM (FORM, SELECT, OPTION, INPUT)
Con i FORM si utilizzano le pagine HTML per inserire valori che vengono poi elaborati sul server. I FORM sono
legati ad applicazioni server-side.
Il browser raccoglie dati dall'utente con un form. Crea una connessione HTTP con il server, specificando una
ACTION (cioè un applicazione che funga da destinatario) a cui fare arrivare i dati. Il destinatario riceve i dati, li
elabora e genera un documento di risposta, che viene spedito, tramite il server HTTP, al browser.
I controlli tipati e nominati vengono usati per l’inserimento dei dati nei form: campi di inserimento dati, pulsanti,
bottoni radio, checkbox, liste a scomparsa, ecc.
Gli elementi di un form sono:
- <form> → contenitore dei widget del form
Attributi:
method: il metodo HTTP da usare (GET, POST in HTML)
action: l'URI dell'applicazione server-side da chiamare
- <input>, <select>, <textarea> → i widget del form.
Attributi:
name: il nome del widget usato dall'applicazione server-side per determinare l'identità del dato
type: il tipo di widget (input, checkbox, radio, submit, cancel, etc.)
N.B.: Tutte le checkboxes e tutti i radio buttons dello stesso gruppo condividono lo stesso nome.
• <button> → bottone cliccabile (diverso dal submit)
• <label> → la parte visibile del widget.
26
Caratteri ammessi negli URI possono essere:
✓ unreserved: utilizzabili liberamente, sono alfanumerici caratteri alfanumerici (lettere maiuscole e minuscolo,
cifre decimali) e alcuni caratteri di punteggiatura non ambigui -_!~*'()
✓ reserved: che hanno delle funzioni particolari in uno o più schemi di URI. In questo caso vanno usati
direttamente quando assolvono alle loro funzioni e devono essere "escaped" per essere usati come parte della
stringa identificativa naturale ;/?:@&=+$
✓ escaped: caratteri riservarti di cui si fa escaping per usarli nelle stringhe identificative (attenzione alle
successive elaborazioni degli URI e dei caratteri riservati).
I caratteri escaped fanno riferimento alle seguenti tipologie di caratteri:
o I caratteri non US-ASCII (cioè ISO Latin-1 > 127)
o I caratteri di controllo: US-ASCII < 32
o I caratteri unwise: { } | \ ^ []`
o I delimitatori: spazio<>#%"
o I caratteri riservati quando usati in contesto diverso dal loro uso riservato
In questo caso i caratteri vanno posti in maniera escaped, secondo la seguente sintassi: %XX, dove XX è il
codice esadecimale del carattere
27
• range: il browser visualizza uno slider per incrementare o decrementare un valore numerico. È possibile
specificare il valore minimo, massimo e l’unità di modifica.
• date: richiede al browser la visualizzazione di un calendario tra cui selezionare una data. Esistono vari tipi
collegati come month, week, time
• search: testo renderizzato in modo diverso su alcuni browser (iPhone)
• color: usato per mostrare una tavolozza di colori, da cui selezionare un codice RGB
VALIDAZIONE AUTOMATICA
HTML 5 prevede anche la possibilità (anzi, è il default) di validare un form client-side, senza ricorrere a funzioni
Javascript aggiuntive.
Dopo l’evento submit i dati inseriti nel form sono verificati in base al tipo di ogni campo (email, URL, etc.). Si può
catturare l’evento invalid e implementare comportamenti specifici.
È possibile inoltre indicare i campi obbligatori, tramite l’attributo required dell’oggetto input.
L’attributo novalidate può essere invece usato per indicare di non validare l’intero form o uno specifico campo.
• ELEMENTI GENERICI
<div> e <span> sono cosiddetti elementi generici: privi di caratteristiche semantiche o presentazionali predefinite,
assumono quelle desiderate con l’aiuto dei loro attributi (style, class, lang).
<div> mantiene la natura di elemento BLOCCO, <span> mantiene a natura di elemento INLINE, ma ogni altra
caratteristica è neutra.
EMBEDDED CONTENT
HTML5 estende notevolmente le possibilità di includere contenuti multimediali nelle pagine e permette di interagire con
questi elementi in modo sofisticato
Alcuni elementi:
<canvas>→ immagini bidimensionali. Definisce area rettangolare in cui disegnare immagini bidimensionali e modificarle
in relazione a eventi, tramite funzioni Javascript. CanvasAPI descrivere questi metodi di manipolazione.
Larghezza e altezza del canvas sono specificati tramite gli attributi width e height dell’elemento <canvas>. Coordinate
(0,0) corrispondono all’angolo in alto a sinistra.
Oggetti non sono disegnati direttamente sul canvas ma all’interno del contesto, recuperato tramite un metodo Javascript
dell’elemento <canvas> chiamato getContext().
<audio>→file audio. Usato per i contenuti sonori. Non esiste tuttavia una codifica universalmente accettata ma è
necessario codificare il video (o audio) in più formati, per renderlo realmente cross-browser.
<video>→file video. Specifica un meccanismo generico per il caricamento di file e stream video, più alcune proprietà
DOM per controllarne l’esecuzione.
Ogni elemento in realtà può contenere diversi elementi che specificano diversi file, tra i quali il browser sceglie quello da
eseguire.
Non esiste tuttavia una codifica universalmente accettata ma è necessario codificare il video (o audio) in più formati, per
renderlo realmente cross-browser.
Il modello ad eventi di DOM è esteso con eventi specifici che permettono la manipolazione degli oggetti. Noi non
guardiamo in dettaglio questi elementi ed API.
28
CSS
CSS lavora su struttura gerarchica. Definisce insieme di regole applicate ai vari elementi.
3. indicato dell'elemento <link>→ Link elemento generico di html che permette di collegare risorsa.
Css strutturato in regole, ogni regola definisce proprietà con sintassi di coppie chiave-valore. Una regola ha un selettore
che dice quali sono gli elementi html su cui applicare le proprietà all’interno della regola ed è delimitata da { }.
#→ quelle regole si applicano a quell’unico e solo elemento html che ha quell’id specificato (#p1 → id = “p1”)
.→ quelle regole si applicano a tutti elementi html che hanno quella class specificata (.title → class = “title”)
Css rispetta CASCATA → per ogni elemento, il suo stile finale va calcolato sulla base di tutte le regole che sono state
applicate quell’elemento. Gli attributi di un elemento vengono presi non da uno (il primo, l'ultimo, ecc.) dei fogli di stile,
ma composti dinamicamente sulla base del contributo di tutti, in cascata.
29
Ad esempio, avendo tre fogli di stile, che riportano ciascuno una delle seguenti regole:
p { font-family: Arial; font-size: 12 pt; }
p { color: red; font-size: 11 pt; }
p { margin-left: 15 pt; color: green;}
Gli attributi dell'elemento p saranno equivalenti a:
p{
font-family: Arial;
font-size: 11 pt;
margin-left: 15 pt;
color: green;
}
p .place →dammi tutti elementi p della classe place
Css rispetta EREDITARIETÀ → proprietà sono ereditate dal padre dell’albero a tutti gli elementi: elementi HTML (e i
contenitori CSS) sono organizzati in una struttura gerarchica.
Regole definite in body si applicano a tutto il sottoalbero (es. a <p>, <div>, ecc al suo interno).
A parte alcune eccezioni, le proprietà CSS degli elementi sono ereditate, ossia assumono lo stesso valore che hanno nel
contenitore dell'elemento a cui si riferisce la proprietà
La proprietà display (che serve per specificare il flusso del testo, es. blocchi vs. inline) NON è ereditata.
SINTASSI
PROPRIETÀ E STATEMENT
PROPRIETÀ = caratteristica di stile assegnabile ad un elemento
CSS1 prevede 53 proprietà diverse, CSS2 ben 121, CSS3 abbiamo perso il conto.
Esempio: color, font-family, margin, ecc.
30
TIPI DI DATO
I valori delle proprietà possono essere di tipo diverso (ci torneremo quando parleremo delle varie proprietà CSS):
• INTERI e REALI: rappresentano numeri assoluti, e sono usati ad esempio per indicare l'indice in caso di elementi
sovrapposti (proprietà z-index)
• URI: indica un URI, ed è usato per caricare risorse esterne, ad esempio importare altri fogli di stile o immagini di
background
• STRINGHE: una stringa posta tra virgolette semplici o doppie. Si usa ad esempio per indicare contenuto generato
automaticamente e aggiunto alla pagina (proprietà content) o il nome di un font
• DIMENSIONI: valori numerici rispetto ad un'unità di misura assoluta (px, pt, in, cm) o relativa(vh, vw, fr, ecc.) o
percentuali
COLORI
I colori sono indicati in tre modi:
1. per nome, come definiti in HTML
2. per codice RGB
• Sintassi rgb(X,X,X) o rgba(X,X,X,O), dove X è un numero tra 0 e 255 mentre O(opacità) è un numero tra 0 e 1
• Sintassi HTML (#XXXXXX)
Esempio: il bianco è specificabile con white oppure rgb(255,255,255) o #FFFFFF
SELETTORI E REGOLE
SELETTORE →permette di specificare un elemento o una classe di elementi dell'albero HTML (o XML) al fine di
associarvi caratteristiche CSS. Esempi: h1, p.codice, img[alt]
31
PROPRIETÀ DI BASE
32
CSS definisce diverse proprietà per controllare questi aspetti e creare layout sofisticati e responsive (ne parleremo nella
seconda parte, ora ci limitiamo ai flussi di base).
CSS E TESTO
CSS definisce molte proprietà per il controllo del testo.
Riassumiamo un po' di terminologia:
• font: collezione di forme di caratteri integrate armoniosamente per le necessità di un documento in stampa.
Tipicamente contiene forme per lettere alfabetiche, numeri, punteggiatura e altri caratteri standard nello scritto.
• font-family (o type face): stile unico che raggruppa molti font di dimensione, peso e stili diversi
• peso: spessore dei caratteri
• stile: effetto sul testo, normale, corsivo o obliquo
Esistono diverse classificazioni dei font, proposte negli anni, e ovviamente moltissimi file di font utilizzabili in CSS.
Importante classificazione distingue i font con grazie (serif) o senza grazie (sans serif), ossia allungamenti
alle estremità dei caratteri.
Proprietà del testo
• font-family: il/i nomi del/dei font (es: "Times New Roman",Georgia,Serif) l'ordine indica una preferenza, importante
indicare sempre il fallback
• font-style:(normal| italic| oblique)
• font-variant: (normal| small-caps)
• font-weight:(normal| bold| bolder| lighter| 100<-> 900),
• font-stretch:(normal| wider| narrower| etc.): caratteristiche del font
• text-indent, text-align: indentazione, allineamento e interlinea delle righe della scatola
• text-decoration(none| underline| overline| line-through| blink),
• text-shadow: ulteriori stili applicabili al testo
• text-transform(capitalize| uppercase| lowercase| none): trasformazione della forma delle lettere
• letter-spacing e word-spacing: spaziatura tra lettere e tra parole
• white-space(normal| pre| nowrap): specificala gestione dei ritorni a capo e del collassamento dei whitespace
all'interno di un elemento
LISTE
CSS definisce alcune proprietà per formattare le liste:
list-style-image: immagine da usare come marker
list-style-position: posizione del marker rispetto al testo (inside | outside)
list-style-type: tipo di marker, ad esempio square, lower-latin, lower-roman, ecc.
TABELLE
Alcune proprietà per formattare le tabelle:
border: bordo delle celle, come per le altre box
border-collapse: indica se i bordi devono essere collassati (separate | collapse)
border-spacing: spazio tra i bordi di due celle adiacenti
caption-side: posizione della didascalia (top | bottom)
CSS – LAYOUT
LAYOUT (o PAGE LAYOUT) → indica la disposizione degli oggetti in modo armonioso nella pagina
Richiede di organizzare gli oggetti: decidere le loro dimensioni e la loro posizione, in relazione agli altri oggetti e alle aree
vuote. CSS definisce diverse proprietà per controllare in modo sofisticato il layout.
Se il contenuto richiede più spazio di quello disponibile:
• RESIZING: si cambiano le dimensioni degli oggetti
• PAGINATION: i contenuti sono divisi su più pagine
• SCROLLING: solo una parte dei contenuti è visibile e si fornisce all'utente un meccanismo per far scorrere i
contenuti visibili
33
LAYOUT RESPONSIVE è ottimizzato per essere letto su tutti i dispositivi →Obiettivo: minimizzare RESIZING e
SCROLLING da parte dell'utente e facilitare l'esperienza di lettura
La costruzione di layout responsive non richiede nuove tecnologie (e non è di per sé una tecnologia) ma è realizzata
direttamente in CSS, specificando il modo in cui il layout si adatta al dispositivo di lettura.
Partiamo dai meccanismi CSS per progettare un layout, per poi arrivare alla responsiveness.
VIEWPORT
Il canvas è lo spazio (virtualmente infinito) di posizionamento degli elementi via CSS.
Il VIEWPORT è la parte del canvas attualmente visibile sullo schermo: è possibile posizionare elementi sul canvas
anche se non visibili attraverso il viewport. Ovviamente il viewport dipende dalla dimensione dello schermo.
I dispositivi di dimensioni ridotte usano un viewport virtuale per calcolare le dimensioni degli oggetti nel layout e
successivamente le scalano per visualizzarle nel viewport reale →tecnica molto utile per layout che non sono progettati
come mobile-first.
Se un layout è progettato per dispositivi più piccoli e per essere modificato in base alle dimensioni del dispositivo (tramite
MEDIA QUERIES ) il viewport virtuale non funziona bene.
Partendo da una proposta di Apple, è stato introdotto l'uso di un elemento META di HTML per controllare il viewport:
Specificando la proprietà "viewport" si possono decidere le dimensioni del viewport e forzare il livello di zoom iniziale:
<meta name="viewport" content="width=device-width, initial-scale=1.0">
Suggerimento: aggiungete sempre questa dichiarazione alle pagine e usate initial-scale=1.0.
UNITÀ DI MISURA BASATE SU VIEWPORT
La più piccola unità indirizzabile sullo schermo è il pixel (px) → dimensioni dei pixel dipendono fortemente dalla
dimensione e dalla risoluzione degli schermi e sono molto diversi tra i vari device e non sono un'unità affidabile.
L'elemento <meta name="viewport"… è usato per controllare questo fattore di scala.
Piuttosto che usare misure in pixel (o in percentuale rispetto al contenitore, poi tradotta in pixel dal browser) si possono
usare unità di misura relative al viewport:
• VIEWPORT WIDTH (VW): una percentuale (1%) della larghezza attuale del viewport. Esempio: in un viewport largo
500 pixel, 3vw = 15px
• VIEWPORT HEIGHT (VH): una percentuale (1%) della altezza attuale del viewport.
LARGHEZZA E ALTEZZA DI UNA BOX
Con le proprietà width e height si fissano larghezza e altezza delle box CSS, esprimibili con dimensioni assolute o relative
→Non usare dimensioni fisse!
Con max-width e max-height si fissano la larghezza ed altezza massime, min-width e min-height per i valori minimi.
Di default larghezza e altezza si applicano alla content-box, escludendo padding e bordi.
La proprietà box-sizing permette cambiare strategia:
• border-box: calcola le misure sull'intera box, compresa di padding e bordo. Molto più comodo per costruire layout
• content-box (default)
FLUSSI INLINE, BLOCCOE FLOAT
I flussi CSS indicano il modo in cui una box è posta rispetto alle altre. Esistono diversi flussi, tra cui quelli base sono:
• flusso BLOCCO: le scatole sono poste l'una sopra l'altra in successione verticale (come paragrafi)
• flusso INLINE: le scatole sono poste l'una accanto all'altra in successione orizzontale (come parole della stessa
riga)
• flusso FLOAT: le scatole sono poste all'interno del contenitore e poi spostate all'estrema sinistra o destra della
scatola, lasciando ruotare le altre intorno.
Ogni elemento HTML ha un flusso di default, che può essere sovrascritto tramite la proprietà display.
34
POSIZIONAMENTO
La posizione dipende dalle altre scatole, dallo sfondo (canvas) o dalla finestra (viewport).
Si usa la proprietà position:
• Posizionamento STATIC (default): la scatola viene posta nella posizione di flusso normale che avrebbe
naturalmente.
• Posizionamento ABSOLUTE: la scatola viene posta nella posizione specificata indipendentemente dal flusso (e
nasconde ciò che sta sotto).
Nota: la posizione è calcolata rispetto al primo elemento contenitore (padre o ancestor) che ha posizione assoluta o
relativa.
• Posizionamento FIXED: la scatola viene posta in una posizione assoluta rispetto alla finestra (viewport), senza
scrollare mai.
• Posizionamento RELATIVE: la scatola viene spostato di un delta dalla sua posizione naturale.
- Elementi figlio possono essere posizionati in modo assoluto. Si usa quindi anche senza "spostare" l'elemento
ma solo per aver un contenitore per posizionare gli elementi figlio.
- Utile anche per poter usare z-index che non si applica ad elementi static.
• Posizionamento STICKY: la scatola viene posta nella sua posizione naturale all'interno del suo contenitore, ma
durante lo scrolling sta fissa rispetto al viewport fino a che il contenitore non esce dalla vista.
Definito il tipo di posizione, si possono controllare coordinate e dimensioni con altre proprietà (fino a 4):
- top, bottom, left, right: coordinate della scatola (rispetto al contenitore o elemento "ancestor" o viewport)
- width, height: dimensioni usabili invece di right e bottom
Se si indicano 4 proprietà, la scatola verrà creata delle dimensioni indicate, ma il contenuto in eccesso può uscirne (lo si
gestisce con la proprietà overflow).
Suggerimento: se non sapete in anticipo quanto contenuto avrete, specificate al massimo 3 proprietà dimensionali.
Gestire correttamente l'overflow di una scatola troppo piena richiede molti sforzi.
POSIZIONAMENTO: OVERFLOW
La proprietà overflow specifica come trattare il contenuto che non sta interamente nella scatola (forse con dimensioni
troppo rigide). Valori possibili:
• VISIBLE: la scatola si espande per contenere tutto il contenuto
• HIDDEN: il contenuto extra viene nascosto
• SCROLL: compare una scrollbar per l'accesso al contenuto extra.
Si possono specificare le proprietà overflow-x and overflow-y per permettere la comparsa di una sola delle scrollbar.
35
OVERLAP E Z-INDEX
Le box possono sovrapporsi, ad esempio in caso di position:relative o absolute (e dropdown o tooltip).
La proprietà z-index permette di indicare la posizione di una box nella pila di box
sovrapposte.
→Più è alto il valore, più l'elemento è in primo piano.
Per default il background delle box è trasparente. Per coprire i contenuti sottostanti deve
essere quindi indicato un colore o un'immagine.
PROPRIETÀ FLOAT
La proprietà float indica che una box deve essere spostata a sinistra o a destra all'interno del contenitore e le altre
box ruotarle intorno.
NOTA: non display:float; ma una proprietà diversa, che può assumere valori left, right o none.
Usata in combinazione con la proprietà clear (left | right | both | none) che indica il lato della box su cui non è possibile
posizionare altri elementi di tipo float, che quindi seguiranno il normale flusso.
È stato lo strumento principale per costruire layout liquidi, in combinazione con la proprietà width per indicare larghezze
percentuali delle box.
CSS FLEXBOX
Il modulo CSS Flexbox è uno strumento estremamente flessibile per costruire layout fluidi senza usare float.
Introduce un nuovo valore per la proprietà display, appunto dispay:flexbox. Gli elementi si dispongono per usare al
meglio lo spazio interno di un FlexBox (scatola flessibile).
Due componenti: un FlexBox container all'interno del quale
sono posizionati i FlexBox item.
Le proprietà di container e item sono usate per decidere:
- direzione in cui disporre gli item
- possibilità di disporre gli item su più linee
- allineamento, spaziatura e ordine degli item
flex-grow, flex-shrink and flex-basis controllano come distribuire lo spazio rimanente dopo aver posizionato gli elementi:
flex: si usa spesso come shorthand per le precedenti flex: 2 1 100px flex: 0 5 flex: 3
36
CSS GRID
Il modulo CSS GRID permette di costruire layout basati su una struttura a griglia, formata quindi da righe e colonne su
cui sono disposti gli elementi.
Anche in questo caso si usa la proprietà display:grid e il layout è formato da un contenitore (GRID CONTAINER) e un
insieme di GRID ITEM.
Le proprietà di contenitore e item permettono di controllare accuratamente il modo in cui la griglia è costruita e i
contenuti sono disposti e visualizzati.
Si possono anche definire template che usano i nomi delle aree per indicare su quali righe e/o colonne saranno
posizionate, tramite la proprietà grid-template-areas.
Le aree saranno poi identificate tramite i valori della proprietà grid-area di ogni grid item.
37
VARIABILI CSS
CSS3 permette di condividere valori tra regole e calcolare dinamicamente i valori delle proprietà→ quindi diventa più
semplice fare operazioni comuni e utili come:
- usare lo stesso colore o lo stesso font in molte regole
- definire regole sulla base di altre regole
- riusare frammenti CSS
Due funzioni che ci vengono in aiuto:
• var(): inserisce il valore di una variabile, dichiarata in precedenza
• calc(): restituisce il risultato di un'espressione aritmetica. Sono ammessi gli operatori + - * /
PREPROCESSORI CSS
Esistono alcuni linguaggi che estendono CSS per semplificare l’uso del linguaggio: alcuni sviluppati prima di
standardizzare variabili e funzioni CSS.
Un PREPROCESSORE CSS è uno strumento che estende la funzionalità di CSS base, consentendo ai progettisti e agli
sviluppatori di scrivere codice CSS in modo più efficiente e organizzato.
Si scrive un CSS in una sintassi più ricca e potente, che sarà poi trasformato nel CSS finale
• COMPILAZIONE: il sorgente viene trasformato per generare un CSS "tradizionale" incluso con i meccanismi
standard
• INTERPRETAZIONE: la pagina contiene uno script client-side che si occupa di processare le regole e applicare gli
stili ottenuti
Ogni preprocessore usa una propria sintassi ed offre alcune funzionalità specifiche ma esistono diversi elementi in
comune:
1. ANNIDAMENTO → Più vicino alla struttura gerarchica di HTML, permette di non ripetere selettori se più elementi
condividono uno stesso elemento padre o antenato. Alternativo alla sintassi compatta di alcune proprietà (es.
font)
38
2. VARIABILI, OPERATORI → CSS supporta l’uso di variabili, i preprocessori le estendono e supportano diversi
operatori per calcolare altri valori.
3. MIXINS →permettono di riusare frammenti di regole. Questi frammenti possono essere parametrizzati.
4. [altri]
FRAMEWORK CSS
BOOTSTRAP CSS
Bootstrap, come gli altri framework, è disponibile in una versione pronta per essere inclusa nelle pagine. CSS ottenuto dal
preprocessing di sorgenti SASS e minificato e JS minificato.
I file possono essere inclusi da remoto (come nell'esempio precedente) o da copie locali.
Minificare: rimuovere tutti i caratteri non necessari dal sorgente, senza modificarne le funzionalità
→difficile da leggere per il programmatore ma occupa meno spazio
→vedi bootstrap.css e bootstrap.min.css
Inoltre, è possibile ri-compilare i sorgenti e personalizzare i valori delle variabili e i moduli da includere.
La compilazione si basa su una serie di script npm, il package manager di NodeJS.
Non ci interessano i dettagli degli script ma i macro-passi che eseguono:
1. Preprocessing SASS (o LASS nelle versioni precedenti)
2. Aggiunta di prefissi per le proprietà specifiche dei browser (con Autoprefixer,
https://github.com/postcss/autoprefixer )
3. Aggiunta di codice CSS e/o JS per aggiustamenti e comportamenti specifici dei browser (browser hacks)
STILI DI DEFAULT
I framework CSS forniscono prima di tutto una formattazione di default per gli elementi HTML.
Mettono a disposizione classi predefinite che possono essere aggiunte agli elementi per ottenere effetti tipografici (in fin
dei conti sono tradotte in regole CSS). Solitamente includono anche set di colori predefiniti.
39
TESTO
Molti framework forniscono classi predefinite per ottenere effetti sul testo.
Attenzione: velocizzano la produzione del codice ma specificano informazioni di stile direttamente sugli elementi, difficili
quindi da generalizzare.
LAYOUT RESPONSIVE
Una delle principali funzionalità dei framework CSS è fornire meccanismi semplici per produrre layout responsive.
Questi meccanismi usano su break-point e media-query ma nascondono la complessità allo sviluppatore.
Il FRAMEWORK:
- fornisce un sistema basato su griglia
- definisce un insieme di classi predefinite per indicare quanto spazio occupa ogni blocco su diversi dispositivi e
viewport
- si occupa di tradurre queste istruzioni in opportuni blocchi @media-query per i diversi dispositivi e viewport
- si fa carico degli aggiustamenti necessari per far funzionare il layout su browser diversi
GRIGLIA IN BOOTSTRAP
Bootstrap definisce una griglia virtuale:
- costruita sul layout flexBox di CSS
- e organizzata per righe e colonne
Ogni riga è divisa in dodicesimi. Ogni elemento può occupare una porzione di 1, 2, ... 12 dodicesimi della larghezza della
riga. Se non si specifica lo spazio occupato da ogni elemento (si usa solo class="col") questo viene distribuito equamente
tra tutti gli elementi della riga.
Per usare una griglia quindi si identifica un elemento contenitore a cui si assegna una classe container o container-
fluid (necessario per usare la griglia). Si aggiunge la classe row agli elementi che corrispondono alle righe. Si definiscono
le colonne, usando le classi predefinite nella forma col - {screen} - {N}
→Per indicare che la colonna su uno schermo di tipo screen occupa N celle su 12. La parte {screen} - si può omettere:
- col-xs-6 occupa metà della larghezza (6 su 12) del contenitore per schermi molto piccoli
- col-sm-4 occupa un terzo della larghezza (4 su 12) del contenitore per schermi piccoli
- col-3 occupa un quarto della larghezza indipendentemente dallo schermo
- col-2 occupa un sesto della larghezza indipendentemente dallo schermo.
40
GRIGLIA IN FOUNDATION
Molti altri framework usano sistemi basati su griglie.
Esempio, anche Foundation usa una griglia divisa in 12 colonne e basata su FlexBox (ha anche una versione basata su
CSS Float).
Questo sistema, chiamato XYGrid, usa alcune classi principali:
- grid-x: identifica una riga
- cell: identifica una cella
- <group>-*: indica il numero di colonne occupate dall'elemento su un dispositivo di un dato gruppo
→<group> corrisponde a un insieme di dispositivi identificati da un breakpoint e anche in questo caso personalizzabili.
COMPONENTI
I framework forniscono diversi componenti grafici come barre di navigazione, tab, pannelli, finestre modali, ecc.
Usano Javascript ma sono richiamabili interamente via markup.
Le proprietà di queste componenti possono essere decise con opportune classi fornite dal framework.
Capacità e flessibilità di ogni componente dipendono dal framework usato.
Molti componenti richiedono plugin Javascript per funzionare (es. Collapse per elementi collassabili, come Accordion).
Alcuni esempi nei file allegati, molti altri nella documentazione di ogni framework.
Le box che compongono i layout visti finora si ridimensionano grazie all'uso di unità di percentuali o relative al viewport.
Questi layout sono detti fluidi proprio per la loro capacità di auto-adattare le dimensioni delle box, ma questo
approccio non è soddisfacente se si usano dispositivi con schermi più piccoli (o più grandi) per cui è utile disporre gli
oggetti in modo diverso ed eventualmente nasconderne qualcuno o cambiarne le proprietà → MEDIA QUERY di CSS
permettono questa ulteriore flessibilità.
MEDIA QUERY
MEDIA QUERY →servono per specificare delle regole particolari che vengono attivate nel caso in cui il supporto usato
per visualizzare la pagina Web soddisfa particolari vincoli. Permettono di adattare automaticamente la
presentazione di una pagina Web a dispositivi differenti senza cambiare il contenuto della pagina.
→Queste condizioni possono essere combinate con operatori logici: AND, OR, NOT.
Si usano le MEDIA-QUERY per specificare il comportamento del layout prima e dopo il breakpoint (condizioni min-
width e max-width).
41
AT RULES
Le MEDIA QUERIES sono un particolare tipo di "AT RULES" (regole precedute da un simbolo “@”) che servono per
specificare ambiti o meta-regole del foglio CSS.
Esempi:
- @charset: serve per specificare l’encoding (es: UTF-8)
- @font-face: permette di specificare i font “customizzati” da utilizzare (vengono scaricati automaticamente)
- @import: permette di importare regole da altri stili
- @namespace: permette di definire namespace all’interno di un CSS ed usarli nei selettori
- @page: serve per definire caratteristiche di margine dell’intera pagina
MULTICOLONNA
In CSS3 è stata introdotta la possibilità di gestire il LAYOUT MULTICOLONNA → contenuto prosegue naturalmente
(ovvero, senza l’uso di tabelle...) da una colonna all’altra: numero delle colonne può essere deciso o variare
automaticamente a seconda della dimensione del viewport.
JAVASCRIPT
ECMAScript→Linguaggio di script client-side. Nato nel 1995 con il nome di JavaScript e standardizzato da ECMA
International nel 1997→ ECMASCRIPT 2015 è la standardizzazione presso ECMA di Javascript.
Ogni elemento del documento ha alcuni eventi associati (click, mouseover, doppio click, tasto di tastiera, ecc), e degli
attributi on+evento associati.
Inserendo istruzioni JavaScript (o chiamata a funzione) nel valore dell'attributo si crea una chiamata callback.
Ci sono due eventi particolari da aggiungere: load (della window) e ready (del documento). Ne riparleremo.
SERVER-SIDE: ROUTING
I servizi server-side sono associati a URI. Il modo più antico e semplice è creare servizi diversi e inserirli in file separati,
ciascuno con un URI proprio. Aprendo una connessione all'URI, viene invocato lo script ed eseguito il servizio.
NodeJs (Express.js, in realtà) fornisce un meccanismo per associare una funzione javascript (CALLBACK) ad ogni tipo
di URI. Aprendo una connessione all'URI, lo script centrale esegue la funzione corrispondente.
In MANIERA SINCRONA, appena lo script viene letto, in un tag <script> o in un file→ Adatto per inizializzare oggetti e
variabili da usare più tardi.
In MANIERA ASINCRONA, associando il codice ad un evento sul documento (e.g., il click su un bottone): event-oriented
processing (tipo più comune di script Javascript).
42
In MANIERA ASINCRONA, associando il codice ad un timeout, i.e., un periodo di attesa dopo il quale lo script viene
eseguito automaticamente.
Durante l’esecuzione dello script, il browser è bloccato e non reagisce agli input dell’utente. Per questo gli script
debbono essere brevi e veloci in modo da lasciare all’utente la sensazione di interattività e controllo.
43
IN CHE MODO JAVASCRIPT È SIMILE AGLI ALTRI LINGUAGGI
TIPI DI DATO
Javascript è minimale e flessibile per quel che riguarda i tipi di dati. Ci sono tre importanti tipi di dati atomici built-in:
1. booleani
2. numeri (sia interi, sia floating point)
3. stringhe
Inoltre, vanno considerati come tipi di dati anche: null e undefined.
C'è unico tipo di dato strutturato, object, di cui fanno parte anche gli array.
VARIABILI
I dati in Javascript sono tipati, ma le variabili no.
var pippo ;
pippo = "ciao" ;
pippo = 15;
pippo = [1, 2, 3] ;
Modi per definire variabili:
• var pippo='ciao' ; definisce una variabile nello scope della funzione o del file in cui si trova.
• let pippo='ciao'; definisce una variabile nello scope del blocco parentetico o della riga in cui si trova.
• const pippo='ciao'; definisce una variabile non ulteriormente modificabile.
OPERATORI
STRUTTURE DI CONTROLLO
44
→ Pessima, molto fragile, se il numero non è corretto o manca
l'attributo href c'è un errore a run time.
FUNZIONI
FUNZIONI in Javascript sono blocchi di istruzioni dotati di un nome e facoltativamente di parametri. Possono ma non
sono obbligate a restituire un valore di ritorno. Le funzioni non sono tipate, i valori di ritorno sì (come al solito).
Se manca un parametro, non restituisce errore ma assume che il parametro sia undefined.
45
Il valore di una proprietà può essere esso stesso un object:
let n1 = 'nome' ;
alert(persona[n1]);
posso anche fare elaborazioni sulle stringhe:
ARRAY
Un ARRAY è un object in cui le chiavi sono numeri interi assegnati automaticamente. Per distinguerlo da un oggetto
normale usa la parentesi quadra invece che la graffa.
let nomi = ['Andrea', 'Beatrice', 'Carlo'] ;
La dot syntax non può essere usata, ma solo quella bracket. Il primo numero è lo zero.
alert(nomi[0] + ' ' + nomi[1]) ;
Posso normalmente leggere e scrivere elementi dell'array: nomi[0] = 'Adriano';
46
Oggetti e array possono contenersi liberamente. Attenzione ad usare parentesi quadre per gli array e graffe per gli
oggetti.
OGGETTI PREDEFINITI
Javascript predefinisce alcuni oggetti utili per raccogliere insieme i metodi più appropriati per certi tipi di dati.
OGGETTI MULTIPLI
o Object
o Array
o String
o Date
o Number
o RegExp
o ...
OGGETTI SINGOLETTO
o Math
o JSON
o ...
47
STRINGHE
L'oggetto String contiene metodi disponibili per tutti i valori di tipo stringa:
JSON
JSON (JavaScript Object Notation) è un formato dati derivato dalla notazione usata da JS per gli oggetti.
DATE
Una data è un oggetto che esprime un giorno e un orario rappresentandolo come il numero di millisecondi trascorsi dalla
mezzanotte del 1 gennaio 1970 e la data in questione. Poiché in realtà è un numero, questo permette di fare operazioni
aritmetiche e confronti numerici.
48
ALTRI OGGETTI
JAVASCRIPT CLIENT-SIDE
• NAVIGATOR : è l’oggetto con le proprietà del client come nome, numero di versione, plug-in installati, supporto per
i cookie, etc.
• WINDOW →ogni finestra separata completamente dalle altre per una questione di sicurezza: è l’oggetto top-
level con le proprietà e i metodi della finestra principale.
➢ FRAME
➢ LOCATION →rappresenta URL della pagina attualmente visualizzata all’interno della finestra. È facilmente
leggibile e modificabile per cambiare pagina visualizzata (Modificando questa proprietà il client accede a un
nuovo URL (redirect)).
➢ HISTORY → l'array degli URL acceduti durante la navigazione = sequenza di navigazione (lista di uri) che
questa specifica finestra ha visto nel tempo. Possibile creare applicazioni client-side dinamiche che ‘navigano
la cronologia’: le librerie di ROUTING mi permettono di simulare navigazione, cioè cambiare uri, manipolando
history e location, anche nelle SPA.
SINGLE PAGE APPLICATION SPA = è un’applicazione in cui non c’è più navigazione, faccio tante cose nella
stessa pagina, cioè l’html è sempre lo stesso.
Nuove applicazioni cambiano stato interno dell’applicazione, contenuto visualizzato nella finestra, navigano nel
contenuto senza navigare nell’uri, cioè senza mai aggiornare l’uri (esempio: se navigo e copio uri, lo invio a
qualcun altro e lo apre non vede stato che vedo io, ma parte da capo).
➢ DOCUMENT →oggetto più importante del browser che rappresenta ciò che è visualizzato attualmente nella
finestra, il contenuto del documento, ed ha proprietà e metodi per accedere ad ogni elemento nella gerarchia.
DOCUMENT rappresenta l'oggetto DOMDocument del DOM del documento visualizzato.
Ogni oggetto nella gerarchia è caratterizzato da un insieme di proprietà, metodi ed eventi che permettono di accedervi,
controllarlo, modificarlo. Javascript nacque per controllare i valori di un form.
49
Aver uniformato l’algoritmo di parsing non è un deterrente per creare pagine “ben formate”, al contrario lascia maggiore
libertà e margine di errore agli sviluppatori. Se esistono pagine errate è perché, in primo luogo, ci sono stati sviluppatori
che hanno creato pagine non valide e usato il "funziona sul mio browser" come strumento di convalida.
Questa brutta pratica è nata dal fatto che, in mancanza di regole semplici (SGML) i browser hanno sempre accettato tutti i
documenti e fatto del loro meglio per visualizzarli: il problema è che in questo modo prolifereranno le pagine non corrette
e sarà più complesso estrarre i dati e implementare manipolazioni automatiche dei contenuti.
Il DOCUMENT OBJECT MODEL è un’interfaccia di programmazione (API) per documenti sia HTML sia XML.
Definisce la struttura logica dei documenti ed il modo in cui si accede e si manipola un documento.
→Utilizzando DOM i programmatori possono costruire documenti, navigare attraverso la loro struttura, e aggiungere,
modificare o cancellare elementi. Ogni componente di un documento HTML o XML può essere letto, modificato,
cancellato o aggiunto utilizzando il Document Object Model→ Quando faccio modifiche al DOM significa cambiare la
schermata e viceversa.
DOM →struttura ad albero dell’oggetto visualizzato sullo schermo della finestra e deriva dal html caricato
precedentemente.
STRUTTURA DI UN DOM:
Il DOM per HTML (non generale!) permette di leggere/scrivere interi elementi, trattandoli come stringhe:
innerHTML: legge/scrive il contenuto di un sottoalbero (escluso il tag dell’elemento radice) = è, in versione html, il
contenuto di un elemento del sottoalbero.
DOM HTML (non il DOM generale) fa meccanismi di navigazione interni al DOM per andare rapidamente da una
parte all’altra (getElementByID, getElementsByName, getElementsByTagName →Ultimi due restituiscono un ‘array’):
50
SELETTORI IN DOM
I metodi standard in DOM per accedere ai nodi di un documento sono:
• getElementById: solo ovviamente se l'elemento ha un id
• getElementsByName: se l'elemento ha un attributo name
• getElementsByTagName: tutti gli elementi con nome specificato
JQuery ha portato in DOM HTML anche tre nuovi selettori (usando selettori css):
• getElementsByClassName; cerca tutti gli elementi di classe specificata
• querySelector: accetta un qualunque selettore CSS e restituisce il primo elemento trovato: equivalente a $()[0] in
JQuery
• querySelectorAll: accetta un qualunque selettore CSS e restituisce tutti gli elementi trovati: equivalente a $() in
JQuery
JAVASCRIPT ED EVENTI DOM →Javascript permette di associare callback di eventi ad oggetti (dichiarazione locale o
globale).
JAVASCRIPT AVANZATO
FALSY E TRUTHY
FALSY = valori che in caso di casting a Booleano diventano falsi (false, 0, null, undefined, “”, NaN)
Ogni altro tipo di valore è TRUTHY (ovvero cast a true) (inclusi "any non-empty string", 3.14, Infinity, {}, [], "0", "undefined",
"null")
FUNZIONE
In Javascript, le FUNZIONI sono oggetti quasi come tutti gli altri, e possono essere:
• Essere assegnate a variabili
• Essere passate come parametri di funzione
• Essere restituite da una funzione
• Essere elementi di un object
• Essere elementi di un array
FUNZIONE = Frammento di codice che può essere richiamato in altre parti di codice con l’operatore ().
51
Posso passare funzioni anonime come parametri di funzione:
Nella chiamata bind(obj,args),obj rappresenta l’oggetto a cui verrà associata la funzione (cosa trovo dentro alla variabile
predefinita this) mentre args sono gli argomenti di ciò che voglio passare alla funzione.
Funzione è una sottoclasse di oggetto che ha un metodo call che attiva codice associato a questo oggetto, ovvero viene
eseguito.
Posso inserire come parametro di una funzione, un’altra funzione. Posso fare che una funzione restituisce un’altra
funzione.
Posso attivare funzione quando voglio.
let potenza è una variabile che contiene una funzione, quindi, ha uno speciale metodo call o () che esegue questa
funzione
Se scrivo potenza() sto eseguendo codice associato a questa funzione.
• Funzioni che appartengono al linguaggio
• Funzioni che appartengono allo script
Come fare un factory in javascript: creo una funzione che restituisce un’altra funzione.
Come fatto nella variabile expGenerator.
52
OBJECT ORIENTEDNESS IN JAVASCRIPT
JavaScript è un LINGUAGGIO OBJECT-ORIENTED anche se non è tipato come Java. In un linguaggio object oriented
tradizionale, la classe è un template sulla base del quale vengono istanziati gli oggetti del programma, specificando i
membri (stati dell'oggetto, valori) e i metodi (comportamenti dell'oggetto, funzioni).
JavaScript ha oggetti, ma non sono basati sul concetto di classe, ma quello di PROTOTIPO. Poiché le funzioni sono
oggetti di primo livello, ogni oggetto può contenere al suo interno delle funzioni, senza ricorrere alla classe. È possibile
istanziare oggetti semplicemente dichiarandone il contenuto, oppure tramite un costruttore.
CLASSI
Le CLASSI non sono entità di primo livello. Al loro posto si usano degli oggetti che provengono dallo stesso costruttore.
Un COSTRUTTORE è una funzione che restituisce un oggetto. Si usa new per usarlo come costruttore dell'oggetto.
JAVASCRIPT: PROTOTYPE
I LINGUAGGI OBJECT-ORIENTED sono divisi in:
• CLASS-BASED (es. SmallTalk, C++, Java, C#, etc.)→classe esiste come concetto esplicito e primario: le classi
formano una gerarchia di tipi, l'ereditarietà avviene tra classi, gli oggetti sono istanze pure delle classi (non hanno
metodi propri). Il design delle interfacce precede ed è strumentale alla creazione degli algoritmi per la esecuzione dei
compiti dell'applicazione. Questo facilita la compilazione e fornisce una base "contrattuale" tra creatori ed utenti
degli oggetti per la garanzia del buon funzionamento del programma.
Ogni oggetto javascript ha una proprietà .prototype a cui si può aggiungere un membro ed associare una funzione.
La modifica del prototipo può avvenire in qualunque momento nell'esecuzione del programma.
Modificare il prototipo cambia non solo le istanze successive, ma anche quelle già generate in precedenza.
53
SCOPE DELLE VARIABILI
Javascript ha tre modi per definire le variabili e 4 tipi di scope delle variabili:
1. VARIABILI GLOBALI = Ogni variabile definita esternamente alle funzioni, indipendentemente dall'operatore
usato (anche niente). Sono considerate membri dell’oggetto predefinito window.
2. VARIABILI DI MODULO = Ogni variabile definita esternamente alle funzioni ma in un file etichettato come
modulo è globale alle funzioni del modulo, ma è locale al modulo.
3. VARIABILI DI FUNZIONE: VARIABILI LOCALI = Ogni variabile definita con var internamente ad una funzione è
locale alla funzione. Lo scope locale sovrascrive lo scope globale.
4. VARIABILI DI BLOCCO = Ogni variabile definita con let o const internamente ad un blocco parentetico è locale al
blocco ed è definita da quel momento in poi. Lo scope di blocco sovrascrive gli altri scope.
→oltre a questi scope, Javascript ha un quinto scope detto CLOSURE che è lo scope della funzione all'interno della
quale viene definita un'altra funzione. Ad esempio, una funzione che restituisce una funzione ha uno scope che è
sempre accessibile alla funzione interna, ma non dal mondo esterno.
Javascript non ha protezione dei membri privati di un oggetto, ma sono tutti accessibili e manipolabili.
OPERATORE SPREAD
L'operatore spread (...) permette di spalmare i singoli elementi di un elemento strutturato (un array, un oggetto, un
iterable) dove ci si aspetterebbe di trovare i singoli elementi ad uno ad uno.
54
AJAX
AJAX (Asynchronous JavaScript And XML) è una tecnica per la creazione di applicazioni Web interattive. Permette
l’aggiornamento asincrono di porzioni di pagine HTML.
Utilizzato per incrementare l’interattività, la velocità e l’usabilità.
Non è un linguaggio di programmazione o una tecnologia specifica.
È un termine che indica l’utilizzo di una combinazione di tecnologie
comunemente utilizzate sul Web:
- HTML e CSS
- DOM (modificabile attraverso JavaScript per la manipolazione
dinamica dei contenuti e dell’aspetto)
- La libreria XMLHttpRequest (XHR) per lo scambio di messaggi
asincroni fra browser e web server
- XML o JSON come meta-linguaggi dei dati scambiati
Inizialmente sviluppato da Microsoft (XMLHttpRequest) come oggetto ActiveX In seguito implementato in tutti i principali
browser ad iniziare da Mozillla 1.0 sebbene con alcune differenze.
Il termine Ajax è comparso per la prima volta nel 2005 in un articolo di Jesse James Garrett.
Pregi:
1. USABILITÀ
Interattività (Improve user experience)
Non costringe l’utente all’attesa di fronte ad una pagina bianca durante la richiesta e l’elaborazione delle pagine (non
più click and-wait)
2. VELOCITÀ
Minore quantità di dati scambiati (non è necessario richiedere intere pagine)
Una parte della computazione è spostata sul client
3. PORTABILITÀ
Supportato dai maggiori browser
Se correttamente utilizzato è platform-independent
Non richiede plug-in
Difetti:
1. USABILITÀ
Non c'è navigazione: il pulsante “back” non funziona, l'inserimento di segnalibri non funziona
Poiché i contenuti sono dinamici non sono correttamente indicizzati dai motori di ricerca
2. ACCESSIBILITÀ
Non supportato da browser non-visuali
Richiede meccanismi di accesso alternativi
3. CONFIGURAZIONE
È necessario aver abilitato Javascript
In Internet Explorer è necessario anche aver abilitato gli oggetti ActiveX
4. COMPATIBILITÀ
È necessario un test sistematico sui diversi browser per evitare problemi dovuti alle differenze fra i vari browser
Richiede funzionalità alternative per i browser che non supportano Javascript
55
XHR: LA RICHIESTA
I valori per ‘readyState’ possono essere: 0 = uninitialize 1 = loading 2 = loaded 3 = interactive 4 = complete
È poi necessario controllare lo status code della risposta HTTP:
56
La complessità di XMLHttpRequest e le differenze di implementazione tra browser e browser hanno portato a suggerire
molte alternative:
• JQUERY è stato introdotto ed è diventato famoso anche perché forniva un meccanismo per fare connessioni Ajax
molto più semplice anche se ancora basato su callback.
JQUERY: AJAX → Una singola funzione si occupa di tutta la comunicazione asincrona usando XMLHttpRequest
(XHR):
membri url e success sono obbligatori. Alcune funzioni equivalenti ($.get(), $.post() e $.put() ) sono disponibili per
maggiore rapidità. Le funzioni success() e error() vengono chiamate appena la connessione HTTP si è conclusa e
dunque readystate = 4 (loaded).
JQUERY: ANCHE CON PROMESSE →Una alternativa al call-back è usare le PROMESSE. Il metodo $.ajax() è già
una promessa, per cui si possono creare catene di funzioni then() con due parametri, la funzione da chiamare in
caso di successo e quella in caso di insuccesso:
AXIOS =libreria open source del 2015 basata su promesse, usata frequentemente su React e Vue.
FETCH = libreria standard dei browser ispirata a jQuery. Un altro modo per fare richieste Ajax basato su promesse.
Ogni singolo passaggio è una promessa, incluso la ricezione e la decodifica della risposta.
• Sia React sia Angular sia Vue introducono librerie interne e/o esterne per fare connessioni Ajax nel loro framework
• Con il passaggio da W3C a WhatWG, e con l'introduzione delle promesse, è stata proposta e standardizzata una
specifica API nativa, chiamata Fetch, per realizzare connessioni Ajax con una libreria nuova NON basata su
XMLHttpRequest.
PROGRAMMAZIONE ASINCRONA
57
L'interprete Javascript prima esegue completamente lo script in corso, e DOPO esegue quelli in callback.
Abbiamo esigenze di asincronicità ogni volta che abbiamo l'esigenza di chiamare un servizio sulla cui disponibilità o sui
cui tempi di esecuzione non abbiamo controllo.
Non ho controllo sui tempi di esecuzione del comando database.search, che potrebbe metterci molto tempo. Nel
frattempo il processo è bloccato in attesa del ritorno della funzione, e l'utente percepisce un'esecuzione a scatti, non
fluida, non responsive.
La situazione potrebbe peggiorare se l’esecuzione avesse necessità, a catena, di tante altre richieste esterne non
controllabili.
58
NODE.JS
NODE.JS = ambiente di esecuzione Javascript progettato per costruire applicazioni server-side efficienti. Nato da un
progetto individuale (di Ryan Dahlnel 2009) è sviluppato con un modello di governance aperto sotto la guida della Node.js
Foundation.
È alla base di un ecosistema di moduli software e supportato da una vasta comunità open-source →Questo ecosistema è
gestito tramite npm(NodePackage Manager).
Si basa sul motore JavaScript V8, open-source, lo stesso motore usato da Google Chrome.
Javascript full stack.
Aspetti principali:
• Modello di esecuzione: SINGLE THREADED, con OPERAZIONI DI I/O NON BLOCCANTI
Node.js utilizza un UNICO THREAD per tutte le richieste ricevute, con un notevole guadagno in termini di efficienza.
Ridotto il tempo di context-switch da una richiesta all'altra
Usa meno memoria, si possono ricevere molte più richieste in parallelo
→Per ottenere questo risultato sfrutta EVENTLOOP e l'ASINCRONICITÀ DI JAVASCRIPT:
- Tutte le richieste sono gestite da un solo processo
- Questo processo passa i task da eseguire (work items) ad altri worker che lavorano in background attraverso la
registrazione di funzioni di callback: registrata una callback quindi l'esecuzione continua e viene processata la
richiesta successiva
- Quando un worker termina la sua esecuzione il thread principale viene notificato (tramite eventi) e la callback
invocata
EVENTLOOP non è una libreria esterna ma un elemento core del motore Node.js →Node.js entra nell'EventLoop
quando viene eseguito lo script ed esce quando non ci sono più funzioni di callback pendenti da invocare.
Internamente usa la libreria libuv for operazioni di I/O asincrone, che a sua volta mantiene un pool di thread.
La comunicazione avviene tramite emissione di eventi: oggetti che possono generare eventi (EVENTEMITTER)
espongono una funzione che permette di associare altre funzioni ad eventi che quell'oggetto genererà
eventEmitter.on(eventName, listener). Al verificarsi dell'evento queste funzioni saranno invocate in modo sincrono.
FUNZIONI ASINCRONE E CALLBACK →Node.jsè quasi esclusivamente basato su FUNZIONI ASINCRONE e
CALLBACK.
La convenzione suggerisce di creare funzioni che accettano una funzione callback asincrona come ultimo
parametro. La funzione callback per convenzione prende in input come primo parametro un oggetto che contiene
l'errore (o meglio un oggetto in cui la funzione che chiamerà la callback avrà memorizzato l'errore).
Resta il problema di callback hell.
Siamo in JS e possiamo usare le tecniche per gestire operazioni asincrone: promesse, async/await, ecc.
• MODULI → permettono di includere altri file JS nelle applicazioni e di riusare librerie esistenti. Favoriscono
l'organizzazione del codice in parti indipendenti e riutilizzabili. L'enorme quantità di moduli disponibili gratuitamente
ha contribuito al successo di Node.js.
Node.js ha un sistema di caricamento dei moduli semplice ma potente:
- un modulo è un file Javascript
- quando si include un modulo, questo viene cercato localmenteo globalmente
Per includere un modulo si usa la keyword require(<modulo>)
59
- foo = require('./lib/bar.js');
- foo = require('bar')
L'interprete cerca il modulo tra quelli core, poi tra le dipendenze locali e poi globali → dipendenze locali e globali si
installano via NPM.
RIUSARE MODULI →i moduli sono eseguiti in uno scope indipendente. Questo permette di evitare conflitti e di
creare librerie facilmente riutilizzabili. I moduli inoltre possono essere assegnati a variabili sulle quali invocare i
metodi che il modulo espone.
CREARE MODULI → Abbiamo bisogno di un meccanismo per rendere gli oggetti visibili dall'esterno del file (lo
scope è interno al file/modulo). Si usa un oggetto speciale module che rappresenta il modulo corrente. L'oggetto
module.exports contiene tutto ciò che il modulo espone pubblicamente. Aggiungere una funzione(o altri oggetti) a
module.exports vuol dire quindi renderlo pubblico e accedibile dall'esterno. Questo stesso meccanismo è usato,
insieme a IIFE, dai moduli che installiamo via NPM
• Estensioni e gestione dei pacchetti via NPM → I moduli di node.js vengono distribuiti ed installati con NPM
(NODE PACKAGE MANAGER) che viene eseguito via command-line e interagisce con il registro npm.
- meccanismo robusto per gestire dipendenze e versioni dei pacchetti (moduli)
- semplice processo di pubblicazione di pacchetti e condividerli con altri utenti.
Una piattaforma per repository pubblici e privati, e servizi enterprise e di integrazione con altri sistemi.
CREARE UN PACCHETTO PER NPM
Un PACCHETTO NPM è un insieme di file Node.js, tra cui il file manifest package.json che specifica alcuni
metadati del pacchetto, tra cui nome, autore, dipendenze, ecc. Il comando npm init eseguito nella directory che
contiene gli script permette di creare il manifest attraverso un'interfaccia testuale intera.
INSTALLARE UN PACCHETTO
Una volta creato un package si possono installare le dipendenze locali: npm install express.
Il comando modifica il file package.json.
Di default i pacchetti sono installati nella directory locale: ./node_modules/
Note:
- nelle versioni precedenti alla 5.0 era necessario specificare il parametro –save per installare i pacchetti in questa
directory, ora non è più necessario.
- l'opzione –g permette invece di installarli globalmente (ovviamente ha bisogno dei permessi).
EXPRESS.JS
Express è un framework server-side per Node.js (Open-source, licenza MIT)→implementa funzioni principali di un
framework server side e gestisce richieste e risposte http:
- ROUTING: associa la richiesta alla funzione che la gestisce. Express fornisce una semplice interfaccia per fare
routing: app.method(path, function(request, response) { ... })
method→ è uno dei metodi HTTP (GET, POST, PUT, ecc.)
path→è il localpathdell'URI richiesto al server
function(req, res) →è un handlerda eseguire quando viene richiesto il path. I due parametri contengono gli object
della richiesta HTTP (uri, intestazioni, parametri, dati, ecc.) e della risposta HTTP in via di restituzione (intestazioni,
dati, ecc.)
- LETTURA RICHIESTA (parametri, querystring, header, ecc.)
- SESSIONI e AUTENTICAZIONE utenti (tramite middleware)
- costruzione della RISPOSTA (status code, body, headers, ecc.)
ROUTE PATHS →possono essere stringhe o espressioni regolari. Express.js controlla l'URL della richiesta e se
individua un "match" invoca l'handler opportuno. Esempi:
- *ab*: tutti i percorsi che contengono ab.
- abc?de: abcde oppure abde
- abc+: abc, abcc, abccc e così via (almeno una c finale)
- store$: path che termina con store
60
ROUTE PARAMETERS →route paths possono contenere parametri, ossia frammenti del path a cui è associato un
nome che può essere usato per recuperare il valore corrispondente.
OGGETTI REQUEST E RESPONSE: le classi REQUEST e RESPONSE rappresentano le richieste e le risposte HTTP ed
espongono i metodi per accedere a tutte le loro informazioni.
Express ha pochissime funzionalità proprie (routing), ma utilizza un grande numero di librerie MIDDLEWARE
personalizzabili in uno stack di servizi progressivamente più complessi.
Aggiungere un middleware allo stack: app.use(<middleware>) .
Un'APPLICAZIONE EXPRESS è allora essenzialmente una sequenza di chiamate a funzioni di middleware tra la
richiesta e la risposta.
Il middleware può:
- accedere agli oggetti di richiesta e risposta
- cambiarli ed eseguire del codice di modifica
- chiamare la prossima funzione del middleware(next())
- uscire dal ciclo e mandare la risposta.
FILE STATICI IN EXPRESS.JS
Express.js può essere usato anche per restituire file statici memorizzati sul server→ Questa funzionalità si realizza
aggiungendo un apposito middleware, che associa ad un path la directory in cui recuperare i file (è possibile
specificare path e directory diverse).
ACCEDERE AI DATI DI UN POST
Appositi middleware sono usati anche per processare dati spediti via POST: libreria bodyparser, ad esempio, permette di
accedere al corpo dei dati spediti dal POST nel body della richiesta. Questi middleware si occupano di recuperare e
elaborare i dati e li convertono in oggetti accedibili dall'applicazione. I dati del POST di un form si accedono come:
<request>.body.<post_variable>
Come negli altri casi, è necessario include il modulo bodyparser e aggiungere il middleware:
bodyparser= require('body-parser');
app.use(bodyparser.urlencoded({ extended: true }));
Lo stesso middleware può essere istanziato per processare dati in JSON: app.use(bodyparser.json()).
ROUNTING MODULARE →La class express.Router permette di creare route handlers modulari e che possono essere
combinati. Anche in questo caso si aggiungere un middleware responsabile di gestire il routing per un insieme di path.
EXPRESS.JS E AUTENTICAZIONE
In Express.js l'autenticazione è realizzata con appositi middleware, devono essere installati, inclusi (con require) e
aggiunti alla propria applicazione (con use).
EXPRESS.JS E CORS
In Express.js si usa il middleware cors per aggiungere gli header Origin e Access-Control-Allow-Origin e supportare CORS.
(Necessario includere il modulo e aggiungere il middleware).
61