Node.js

Transcript

Node.js
Dott.Ing.Ivan Ferrazzi
Node.js
Introduzione
alla
programmazione
Dott. Ing. Ivan Ferrazzi
V1.0 del 05/11/2012
1/15
Dott.Ing.Ivan Ferrazzi
Copyright ©2012 Dott.Ing. Ivan Ferrazzi
Permission is granted to copy, distribute and/or modify this
document under the terms of the GNU Free Documentation
License, Version 1.2 or any later version published by the
Free Software Foundation; with no Invariant Sections, no
Front-Cover Texts, and no Back-Cover Texts.
2/15
Dott.Ing.Ivan Ferrazzi
Indice generale
INTRODUZIONE....................................................................................................4
CONCETTI BASE...................................................................................................6
Gli oggetti........................................................................................................6
Gli eventi.........................................................................................................8
Le finestre di dialogo.....................................................................................10
Le finestre......................................................................................................12
Concatenare diversi elementi........................................................................13
I FORM...............................................................................................................15
Interagire con i componenti di un modulo FORM...........................................15
VARIABILI ED OGGETTI......................................................................................18
Operazioni con variabili.................................................................................18
Le stringhe oggetto String.............................................................................19
Oggetto Date.................................................................................................22
Oggetto Image...............................................................................................23
Oggetto frame e parent.................................................................................24
Gli array.........................................................................................................25
LE FUNZIONI......................................................................................................27
Concetto base................................................................................................27
Variabili locali e globali..................................................................................29
IL RICHIAMO DI OGGETTI...................................................................................30
Come utilizzare getElementById().................................................................30
COMANDI CONDIZIONALI E CICLI.......................................................................32
Comando condizionale if...else......................................................................32
Il comando condizionale switch.....................................................................33
Il ciclo for.......................................................................................................34
Il ciclo while...................................................................................................35
3/15
Dott.Ing.Ivan Ferrazzi
INTRODUZIONE
Concetto
Node.js è un framework che ci permette di creare applicativi server-side
sfruttano il linguaggio Javascript normalmente utilizzato per la realizzazione di
codice client-side.
Il sistema si basa su Javascript Engine V8 della Google ed è disponibile per le
maggiori piattaforme. Node.js sfrutta la programmazione ad eventi, ossia la
programmazione basata sul modello “event-driven”. Il programma rimane in
attesa di specifici eventi ai quali il sistema reagisce in determinata maniera. Il
tutto avviene in maniera asincrona per garantire una maggiore efficienza di
elaborazione.
Installazione
Per installare il pacchetto node.js scarichiamo l'ultima versione in formato
.tar.gz e lo installiamo da sorgente utilizzando la classica procedura:
#
#
#
#
#
tar xzf nodejs-vxx.tar.gz
cd nodejs-vxx
./configure
make
make install
Per verificare che l'installazione sia andata a buon fine digitiamo da terminale
# node
4/15
Dott.Ing.Ivan Ferrazzi
> console.log(1)
1
5/15
Dott.Ing.Ivan Ferrazzi
IL LINGUAGGIO
Il mio primo programma nodejs
Creiamo ora un piccolo programma nodejs che manda la stringa
“Buongiorno a tutti!” direttamente sullo standard output della console.
Apriamo un editor e scriviamo il seguente codice:
console.log(“Buongiorno a tutti!”);
Salviamo ora il file con il nome buongiorno.js e mandiamo in esecuzione il
programma da terminale come segue:
$ node buongiorno.js
Buongiorno a tutti!
In questo caso utilizziamo l'oggetto console che metta a disposizione il
metodo log() con il quale si può mandare una stringa sullo standard
output della console stessa.
I moduli di nodejs
Il sistema base di nodejs mette a disposizione un numero limitato di
metodi utilizzabili direttamente all'interno del codice. Per aggiungere
nuove funzionalità dobbiamo integrare dei moduli dove ogni modulo
aggiunge una classe o singoli metodi utilizzabili all'interno del codice. I
singoli moduli vengono importati con il metodo di base require come
6/15
Dott.Ing.Ivan Ferrazzi
segue:
var url = require('url');
Normalmente si cerca di utilizzare come nome della variabile lo stesso
del modulo importato. In questo caso viene creato l'oggetto dal modulo
url richiamabile dall'omonima variabile di oggetto
url. Andiamo ad
analizzare alcuni dei moduli messi a disposizione da nodejs.
Il modulo globals
Questo modulo non viene importato perché già presente all'interno del
sistema base. Ecco perché è possibile utilizzare alcuni oggetti come
console per interagire con lo standard output ed output degli errori,
oppure variabili come __filename che fornisce a livello di runtime il nome
del file avviato e __dirname che ne fornisce la cartella corrente.
Il modulo http
Questo modulo contiene la classe http.Server che permette di avviare un
server web con una serie di oggetti in grado di ottimizzare questa
funzione.
Il modulo url
Questo modulo permette di creare, trasformare e manipolare gli url sotto
forma di oggetti o stringhe. Cerchiamo di capire il funzionamento di
questo modulo partendo dal seguente esempio:
http://user:[email protected]:8080/p/a/t/h?query=string#hash
Le singole parti dell'url vengono definite come segue:
href
protocol
host
auth
hostname
port
pathname
search
path
query
hash
identifica l'intera url
identifica il protocollo usato, ossia http:
identifica il nome di dominio con il numero della porta,
ossia host.com:8080
identifica la parte utilizzata per l'autenticazione, ossia
user:pass
identifica solamente il dominio, ossia host.com
identifica solo la porta utilizzata, ossia 8080
identifica il percorso alla risorsa, ossia /p/a/t/h
identifica la parte relativa alla richiesta inviata alla
relativa pagina, ossia ?query=string
identifica l'insieme tra pathname e search
identifica solamente l'elenco delle informazioni GET
passate alla relativa pagina, ossia query=string
identifica la parte di ancoraggio all'interno della pagina,
ossia #hash
7/15
Dott.Ing.Ivan Ferrazzi
Verranno ora una serie di metodi che si hanno a disposizione con l'utilizzo
di questo modulo:
url.parse(urlStr, [parseQueryString], [slashesDenoteHost])
Questo metodo converte una stringa in un oggetto. Se parseQueryString
è true la query string viene elaborata dal modulo querystring. Se
settiamo come true il terzo parametro allora //foo/bar viene suddiviso in
host (//foo) e pathname (/bar), piuttosto che pathname (//foo/bar).
var url = require('url');
var obj = url.parse('http://www.google.it/index.html?cerca=12');
console.log(obj);
restituisce il seguente risultato
{ protocol: 'http:',
slashes: true,
host: 'www.google.it',
hostname: 'www.google.it',
href: 'http://www.google.it/index.html?cerca=12',
search: '?cerca=12',
query: 'cerca=12',
pathname: '/index.html',
path: '/index.html?cerca=12' }
url.format(urlObj)
Recupera le informazioni dell'oggetto urlObj e ne crea una relativa stringa
url.
Il modulo path
Questo modulo permette di gestire i percorsi reali del sistema operativo.
path.join([path1],[path2],[...])
Questa funzione concatena una serie di percorsi restituendo il percorso
effettivo:
path.join('/foo', 'bar', 'baz/asdf', 'quux', '..')
restituisce la seguente stringa:
'/foo/bar/baz/asdf'
path.resolve([from ...], to)
Questa funzione esegue una serie di cd e restituisce infine la personal
work directory.
8/15
Dott.Ing.Ivan Ferrazzi
path.resolve('/foo/bar', '../baz')
restituisce
'/foo/baz'
path.relative(from, to)
Restituisce il percorso relativo per arrivare al percorso to partendo da
from.
path.relative('./orandea/test/aaa', './orandea/impl/bbb')
restituisce
'../../impl/bbb'
path.dirname(p)
Questa funzione restituisce il precorso al file.
path.dirname('/foo/bar/baz/asdf/quux')
restituisce
'/foo/bar/baz/asdf'
path.basename(p, [ext])
Possiamo utilizzare questa funzione per recuperare il solo nome del file
senza il percorso come segue:
path.basename('/foo/bar/baz/asdf/quux.html')
restituisce
'quux.html'
path.basename('/foo/bar/baz/asdf/quux.html', '.html')
restituisce
'quux'
path.extname(p)
Questa funzione restituisce l'estensione del file fornito. 'index.html'
restituisce '.html', 'index.' restituisce '.', mentre 'index' restituisce una
stringa vuoto.
9/15
Dott.Ing.Ivan Ferrazzi
Il modulo fs (file system)
Questo modulo, in combinazione con il modulo path, permette di gestire
al meglio le operazioni sul file system come copiare, rinominare,
spostare, leggere e/o scrivere nei file. Vediamo alcune delle funzioni più
importanti. Il modulo contiene dei metodi con elaborazione sincrona ed
altri con elaborazione asincrona.
Vediamo qui di seguito alcuni dei metodi asincroni:
fs.rename(oldPath, newPath, [callback])
Questa funzione permette di rinominare un file come segue:
fs.rename('/tmp/hello', '/tmp/world', function (err) {
if (err) throw err;
console.log('renamed complete');
});
La funzione di callback recupera lo stato dell'esito della funzione stessa.
fs.unlink(path, [callback])
La funzione unlink permette di cancellare un file identificato da path:
fs.unlink('/tmp/hello', function (err) {
if (err) throw err;
console.log('successfully deleted /tmp/hello');
});
fs.mkdir(path, [mode], [callback])
Questa funzione crea la cartella path. Il parametro mode è settato a 0777.
fs.readdir(path, [callback])
Con questa funzione possiamo leggere il contenuto di una cartelle. La
funzione di callback si aspetta infatti due parametri err e files dove files
è un array che contiene i file tranne '.' e '..' .
fs.readFile(filename, [encoding], [callback])
Questa funzione legge il contenuto di un file come segue:
fs.readFile('/etc/passwd', 'utf-8', function (err, data) {
if (err) throw err;
console.log(data);
});
Nella funzione di callback il parametro data ha come valore il contenuto
del file.
fs.writeFile(filename, data, [encoding], [callback])
Questa funzione prende la stringa data e la salva all'interno del file
indicato da filename. Vediamo un semplice esempio:
10/15
Dott.Ing.Ivan Ferrazzi
fs.writeFile('message.txt', 'Hello Node', function (err) {
if (err) throw err;
console.log('It\'s saved!');
});
fs.appendFile(filename, data, encoding='utf-8', [callback])
Per aggiungere la stringa contenuta in data nel file filename usiamo la
funzione come segue:
fs.appendFile('message.txt', 'data to append', function (err) {
if (err) throw err;
console.log('The "data to append" was appended to file!');
});
fs.stat(path, [callback])
Questa funzione viene utilizzata per recuperare informazioni sul file
indicato da path. La funzione di callback utilizza due parametri err e stats
dove stats è un oggetto che al suo interno ha una serie di informazioni.
L'oggetto stats ha inoltre una serie di funzioni che permettono di
effettuare delle verifiche sul file stesso:
stats.isFile()
stats.isDirectory()
stats.isBlockDevice()
stats.isCharacterDevice()
stats.isSymbolicLink() (only valid with fs.lstat())
stats.isFIFO()
stats.isSocket()
Vediamo ora un esempio per capirne il funzionamento:
fs.stat('/tmp/dir', function (err, stats) {
if(err) {
console.log('error');
}else{
console.log('stats: ' + JSON.stringify(stats));
if(stats.isDirectory()) {
console.log("directory");
}
}
});
I metodi sincroni si riconoscono dal mancato utilizzo della funzione di
callback. Vediamo ora alcune delle funzioni sincrone:
fs.statSync(path)
Questo metodo funziona come fs.stat, ma restituisce l'oggetto stats
come risultato della funzione stessa:
var stats = fs.statSync('file');
fs.readdirSync(path)
11/15
Dott.Ing.Ivan Ferrazzi
Questo metodo funziona come fs.readdir, ma restituisce l'array files
come risultato della funzione stessa:
var files = fs.readdirSync('dir');
console.log(files.length);
Il modulo util
Questo modulo contiene una serie di funzioni in grado di ottimizzare il
lavoro con le variabili.
Il modulo net
Questo modulo mette a disposizione uno strumento per la realizzazione
di applicativi server-client che si basano sui socket.
Il modulo querystring
Questo modulo permette di creare una stringa di valori (nome=valore)
concatenati dal carattere & da un oggetto e viceversa. La funzione
querystring.stringify(obj, [sep], [eq])
permette di creare una stringa da un oggetto mentre la funzione
querystring.parse(str, [sep], [eq], [options])
è in grado di fare l'opposto, ossia creare un oggetto da una stringa.
Vediamo alcuni semplici esempi:
querystring.stringify({ foo: 'bar', baz: ['qux', 'quux'], corge: '' })
restituisce la stringa
'foo=bar&baz=qux&baz=quux&corge='
mentre
querystring.stringify({foo: 'bar', baz: 'qux'}, ';', ':')
restituisce
'foo:bar;baz:qux'
Semplice server http
Con il seguente programma vediamo come creare un semplice server
http che ad una nostra richiesta risponde con il testo “BUON GIORNO!”.
12/15
Dott.Ing.Ivan Ferrazzi
Digitiamo il seguente codice all'interno di un editor di testi e salviamolo
con il nome buongiorno.js:
var http = require('http');
var server = http.createServer(
function (req, res) {
res.writeHead(200, {'Content-Type': 'text/html'});
res.write('<html>' +
'<head></head>' +
'<body>BUON GIORNO!</body>' +
'</html>');
res.end();
}
);
server.listen(1234, '127.0.0.1');
console.log('server in esecuzione...');
Nella prima riga richiamiamo il modulo http all'interno della variabile
oggetto http. Riprendiamo poi l'oggetto per creare il server con
createServer che utilizza una funzione callback con i parametri req e res.
Nel momento in cui il server risponderà ad una richiesta il sistema
richiamerà questa funzione passando la richiesta http come oggetto nella
variabile req, mentre l'oggetto res verrà utilizzato per impostare
l'eventuale risposta del server.
Nel nostro caso utilizziamo quest'ultimo per impostare l'intestazione della
risposta con writeHead ed il testo di risposta in chiusura con write.
Infine definiamo la porta e l'indirizzo ip sul quale vogliamo attivare il
nostro server.
Ora facciamo partire il programma con
# node buongiorno.js
e proviamo ad effettuare una richiesta dal browser con
http://localhost:1234
Moduli propri
Vediamo ora come poter creare i nostri propri moduli da importare nei
nostri codici. Un progetto sviluppato con Node.js utilizza di norma un file
di nome index.js all'interno del quale si importano tutti i moduli necessari
al buon funzionamento del progetto stesso. Il sistema che utilizza Node.js
per riconoscere un file .js come modulo è quello di esportare le funzioni
accessibili dall'esterno con la parola exports. Per far diventare modulo il
file buongiorno.js creato precedentemente lo modifichiamo come segue:
var http = require('http');
function saluto() {
13/15
Dott.Ing.Ivan Ferrazzi
}
var server = http.createServer(
function (req, res) {
res.writeHead(200, {'Content-Type': 'text/html'});
res.write('<html>' +
'<head></head>' +
'<body>BUON GIORNO!</body>' +
'</html>');
res.end();
}
);
server.listen(1234, '127.0.0.1');
console.log('server in esecuzione...');
exports.saluto = saluto;
All'interno del file index.js importiamo il modulo appena creato come
segue:
var buongiorno = require('./buongiorno');
buongiorno.saluto();
URL parsing
La cosa più importante all'interno di un webserver è quella di mandare al
client contenuti diversi in base a richieste diverse. Vediamo come poter
recuperare le informazioni dalla richiesta inviata dal browser.
Partiamo dal seguente esempio:
var http = require('http');
var server = http.createServer(
function (req, res) {
console.log(req.url);
res.writeHead(200, {'Content-Type': 'text/html'});
res.write('<html>' +
'<head></head>' +
'<body>BUON GIORNO!</body>' +
'</html>');
res.end();
}
);
server.listen(1234, '127.0.0.1');
console.log('server in esecuzione...');
La variabile url dell'oggetto req all'interno della funzione di callback
restituisce
il
percorso
alla
risorsa
richiesta.
L'indirizzo
url
http://localhost:1234 genera il valore url /, mentre la richiesta
http://localhost:1234/chisiamo.html genera il valore url /chisiamo.html.
Ecco che possiamo utilizzare questa informazione per mandare al
browser la pagina richiesta.
var http = require('http');
function getHomePage() {
14/15
Dott.Ing.Ivan Ferrazzi
}
var html = '<html>' +
'<head></head>' +
'<body>HOMEPAGE</body>' +
'</html>';
return html;
function getChiSiamo() {
var html = '<html>' +
'<head></head>' +
'<body>CHI SIAMO</body>' +
'</html>';
return html;
}
var server = http.createServer(
function (req, res) {
console.log(req.url);
res.writeHead(200, {'Content-Type': 'text/html'});
var html = '';
if(req.url == '/chisiamo.html') {
html = getChiSiamo();
}else{
html = getHomePage();
}
res.write(html);
res.end();
}
);
server.listen(1234, '127.0.0.1');
console.log('server in esecuzione...');
Moduli JSCommon con NPM
NPM, oltre ad essere una repository delle librerie scritte per Node.js, è un
comando per scaricare, ricercare ed aggiornare i vari software utilizzabili.
NPM può essere semplicemente installato con curl come segue
# curl http://npmjs.org/install.sh | sh
mentre per installare i vari pacchetti si usa
# npm install {pacchetto}
L'elenco dei moduli disponibili per Node.js si possono trovare all'indirizzo
https://npmjs.org/
L'importazione del modulo all'interno del codice si ottiene con la parola
require come segue:
var modulo = require('{nome_modulo}');
15/15