Prelegere din cadrul materiei "Dezvoltarea aplicaţiilor Web cu JavaScript" (Full-Stack Web Development) predată de Dr. Sabin Buraga (oct.2019–feb.2020).
Resurse suplimentare la https://profs.info.uaic.ro/~busaco/teach/courses/staw/web-film.html
5. Dr.SabinBuragaprofs.info.uaic.ro/~busaco
Încărcarea & redarea documentelor
context de navigare
mediu în care sunt redate obiectele de tip Document
exemple tipice:
tab-ul unei instanțe de browser Web
elementul <iframe> în care se încarcă o altă resursă
7. Dr.SabinBuragaprofs.info.uaic.ro/~busaco
Încărcarea & redarea documentelor
context de navigare
include un istoric al sesiunii curente (session history)
memorând secvența instanțelor de tip Document
care au fost redate utilizatorului
documentul curent e considerat ca fiind document activ
10. Dr.SabinBuragaprofs.info.uaic.ro/~busaco
Încărcarea & redarea documentelor
context de navigare
posedă un proprietar (creator browsing context)
desemnat de o origine (origin)
originile pot fi partajate și sunt imutabile, în general
doar domeniul unei origini poate fi alterat
via proprietatea document.domain
12. Dr.SabinBuragaprofs.info.uaic.ro/~busaco
Încărcarea & redarea documentelor
context de navigare
anumite elemente – de exemplu, <iframe> –
pot instanția alte contexte:
contexte imbricate (nested browsing contexts)
astfel, un context imbricat are asociat un context părinte
pot exista diverse contexte copil „legate”
de un context părinte
13. Dr.SabinBuragaprofs.info.uaic.ro/~busaco
Încărcarea & redarea documentelor
context de navigare
anumite elemente – de exemplu, <iframe> –
pot instanția alte contexte:
contexte imbricate (nested browsing contexts)
un context imbricat poate fi setat să întârzie încărcarea
unei resurse (delaying load events mode)
15. Dr.SabinBuragaprofs.info.uaic.ro/~busaco
Încărcarea & redarea documentelor
context de navigare
poate avea asignat un nume (browsing context name)
denumiri speciale – valori ale atributului target
desemnând numele contextului de navigare:
_blank _self _parent _top
<a href="http://undeva.info/" target="_blank">…</a>
16. Dr.SabinBuragaprofs.info.uaic.ro/~busaco
Încărcarea & redarea documentelor
remarcă:
un document (instanță de tip Document)
nu trebuie obligatoriu să aibă atașat un context
cazuri tipice:
instrumente de indexare a conținutului
(roboți ai motoarelor de căutare)
sau
instanțe de navigator Web neinteractiv (headless browser)
18. Dr.SabinBuragaprofs.info.uaic.ro/~busaco
Încărcarea & redarea documentelor
uzual, unei instanțe de tip Document
îi corespunde un obiect Window (relație 1-la-1)
excepție:
reutilizarea unui obiect Window pentru prezentarea
altei instanțe de Document în cadrul aceluiași context
e.g., înlocuirea unui document vid (about:blank) cu altul
19. Dr.SabinBuragaprofs.info.uaic.ro/~busaco
Încărcarea & redarea documentelor
uzual, unei instanțe de tip Document
îi corespunde un obiect Window (relație 1-la-1)
excepție:
refolosirea unei instanțe de Document pentru a încărca
alte obiecte Window via metoda document.open()
25. Dr.SabinBuragaprofs.info.uaic.ro/~busaco
politica de caching e specificată de un fișier .appcache
referit prin <html manifest="offline.appcache">
pentru fiecare pagină Web a aplicației
CACHE MANIFEST
# Aplicație Web minunată (versiunea 1.0.1)
# resurse (proprii / din alte domenii) ce pot fi plasate în cache
index.html
cache.html
html5.css
fig.jpg
img/logo.png
http://www.penguin.info/tux.css
# preia de pe rețea conținutul unor resurse, dacă e posibil
NETWORK:
news.html
# conținut alternativ, dacă suntem offline
FALLBACK:
/fallback.html
27. Dr.SabinBuragaprofs.info.uaic.ro/~busaco
Control asupra cache-ului navigatorului Web
ApplicationCache
actualmente, această tehnică e considerată învechită
“This feature is in the process of being removed from
the Web platform. (This is a long process that takes many years.)
Using any of the offline Web application features at this time
is highly discouraged. Use service workers instead.”
conform html.spec.whatwg.org/multipage/offline.html#offline
29. Dr.SabinBuragaprofs.info.uaic.ro/~busaco
Specificarea contoarelor de timp
WindowTimers
observații (HTML Living Standard, 26 noiembrie 2019):
“Timers can be nested; after 5 such nested timers, however,
the interval is forced to be at least four milliseconds.”
“This API does not guarantee that timers will run exactly
on schedule. Delays due to CPU load, other tasks, etc,
are to be expected.”
30. Dr.SabinBuragaprofs.info.uaic.ro/~busaco
Starea și proprietățile sistemului
interfața Navigator având sub-interfețele:
NavigatorID – identitatea browser-ului
NavigatorLanguage – preferințe lingvistice ale clientului
NavigatorOnline – starea online/offline a navigatorului
NavigatorContentUtils – manipularea conținuturilor
NavigatorCookies – informații privind cookie-urile
NavigatorPlugins – managementul plugin-urilor
NavigatorConcurrentHardware – arhitectura hardware
html.spec.whatwg.org/multipage/system-state.html#system-state-and-capabilities
33. Dr.SabinBuragaprofs.info.uaic.ro/~busaco
Starea și proprietățile sistemului
remarcă:
“In certain cases, despite the best efforts of the entire
industry, Web browsers have bugs and limitations
that Web authors are forced to work around.” (W3C, 2019)
detectarea clientului trebuie întotdeauna
să ia în considerație versiunile actuale
se presupune că versiunile viitoare/necunoscute
vor fi compatibile cu cea curentă
34. Dr.SabinBuragaprofs.info.uaic.ro/~busaco
Starea și proprietățile sistemului
protocoalele și/sau tipurile de date
ce pot fi gestionate de navigatorul Web
pot fi manipulate via interfața NavigatorContentUtils
registerProtocolHandler() registerContentHandler()
implicit, într-un URI se permit scheme precum:
bitcoin irc geo mailto magnet mms news nntp sip
sms smsto ssh tel urn webcal xmpp
35. Dr.SabinBuragaprofs.info.uaic.ro/~busaco
Starea și proprietățile sistemului
protocoalele și/sau tipurile de date
ce pot fi gestionate de navigatorul Web
pot fi manipulate via interfața NavigatorContentUtils
tipuri Media-Type (MIME) uzuale:
application/x-www-form-urlencoded application/xhtml+xml application/xml
image/gif image/jpeg image/png image/svg+xml
text/cache-manifest text/css text/html text/plain text/xml
36. Dr.SabinBuragaprofs.info.uaic.ro/~busaco
Managementul istoricului navigării
(HTML Living Standard, 26 noiembrie 2019)
enum ScrollRestoration { "auto", "manual" };
[Exposed=Window]
interface History {
readonly attribute unsigned long length;
attribute ScrollRestoration scrollRestoration;
readonly attribute any state;
void go (optional long delta = 0);
void back ();
void forward ();
void pushState (any data, DOMString title, optional USVString? url = null);
void replaceState (any data, DOMString title, optional USVString? url = null);
};
html.spec.whatwg.org/multipage/history.html
40. Dr.SabinBuragaprofs.info.uaic.ro/~busaco
Drag & drop
stocarea fragmentelor de date în diverse formate,
în vederea efectuării operațiilor drag & drop
html.spec.whatwg.org/multipage/interaction.html#drag-and-drop
developer.mozilla.org/Web/API/HTML_Drag_and_Drop_API
41. Dr.SabinBuragaprofs.info.uaic.ro/~busaco
Drag & drop
un element HTML poate fi sursă pentru drag & drop
dacă are atașat atributul draggable="true" și are definită
o funcție de tratare a evenimentului dragstart
ce stochează datele ce vor fi transferate către destinație
42. Dr.SabinBuragaprofs.info.uaic.ro/~busaco
Drag & drop
datele de transferat vor fi stocate
de un obiect DataTransfer
developer.mozilla.org/Web/API/DataTransfer
se permit diverse operații – precizate de effectsAllowed:
copiere (copy copyLink)
mutare (move linkMove),
realizarea unei legături (link) etc.
43. Dr.SabinBuragaprofs.info.uaic.ro/~busaco
Drag & drop
destinatarul operațiunii drag & drop va avea definit
atributul dropzone a cărui valoare specifică tipul MIME
al datelor ce vor fi acceptate
e.g., string:text/plain pentru a accepta orice șir de caractere
sau file:image/jpeg pentru un fișier JPEG
46. Dr.SabinBuragaprofs.info.uaic.ro/~busaco
Drag & drop
pentru exemplificări și alte detalii, a se consulta:
dev.opera.com/articles/view/drag-and-drop/
www.html5rocks.com/tutorials/dnd/basics/
bestvpn.org/html5demos/drag/
www.tutorialspoint.com/html5/html5_drag_drop.htm
49. Dr.SabinBuragaprofs.info.uaic.ro/~busaco
WebSocket API
definește un API abstract pentru transmiterea de date
pe baza protocolului de transfer WebSocket – RFC 6455
detalii disponibile în specificația HTML Living Standard
(26 noiembrie 2019)
html.spec.whatwg.org/multipage/web-sockets.html
50. Dr.SabinBuragaprofs.info.uaic.ro/~busaco
WebSocket API
un program JavaScript rulat de navigatorul Web poate
trimite mesaje de tip cerere spre o aplicație invocată
la nivel de server pentru a recepționa, ulterior, mesaje de
tip răspuns în mod asincron (event-driven responses)
succesor al abordării Comet – Reverse Ajax
51. Dr.SabinBuragaprofs.info.uaic.ro/~busaco
[Exposed=(Window,Worker)]
interface WebSocket : EventTarget {
constructor (USVString url,
optional (DOMString or sequence<DOMString>) protocols = []),
readonly attribute USVString url;
const unsigned short CONNECTING = 0; // constante: starea conexiunii
const unsigned short OPEN = 1;
const unsigned short CLOSING = 2;
const unsigned short CLOSED = 3;
readonly attribute unsigned short readyState;
readonly attribute unsigned long bufferedAmount;
attribute EventHandler onopen; // funcții de tratare a evenimentelor
attribute EventHandler onerror; // vizând comunicarea asincronă
attribute EventHandler onclose; // a datelor prin rețea
readonly attribute DOMString extensions;
readonly attribute DOMString protocol;
specificația WebIDL a interfeței
52. Dr.SabinBuragaprofs.info.uaic.ro/~busaco
// închiderea conexiunii
void close (optional unsigned short code, optional USVString reason);
// diverse maniere de transfer de mesaje (date)
attribute EventHandler onmessage;
attribute BinaryType binaryType; // { "blob", "arraybuffer" };
void send (USVString data);
void send (Blob data);
void send (ArrayBuffer data);
void send (ArrayBufferView data);
}
de studiat și developer.mozilla.org/Web/API/WebSockets_API
54. Dr.SabinBuragaprofs.info.uaic.ro/~busaco
// creăm un socket Web
var sock = new WebSocket ("ws://www.undeva.info/");
// asociem funcțiile de tratare a evenimentelor
sock.onopen = function (ev) {
// socket-ul a fost deschis, transferul datelor poate începe…
};
sock.onclose = function (ev) {
console.log ("Socket-ul a fost închis; cod de stare: " + ev.code)
};
sock.onmessage = function (ev) {
console.log ("Am recepționat mesajul: " + ev.data);
};
sock.onerror = function (ev) {
console.error ("A survenit o eroare…");
};
// trimitem date
sock.send ("Salutări hibernale! :)");
// am închis conexiunea
sock.close (); maniera generală de
transfer al datelor
55. Dr.SabinBuragaprofs.info.uaic.ro/~busaco
// actualizările de date vor fi trimise cu rata de o actualizare
// la fiecare 33ms, dacă rețeaua oferă suficientă lățime de bandă
var sock =
new WebSocket ('ws://joc.undeva.org:19740/updates');
sock.onopen = function () {
setInterval (function() {
if (sock.bufferedAmount === 0)
sock.send (oferaDate ());
}, 33);
};
oferă numărul de octeți
ce n-au fost transmiși încă
56. Dr.SabinBuragaprofs.info.uaic.ro/~busaco
// exemplu în contextul IoT (Internet of Things):
// implementarea unui comutator pentru a controla o veioză
sock.onmessage = (ev) => {
if (event.data == 'on') {
lamp.turnOn();
} else if (ev.data == 'off') {
lamp.turnOff();
}
};
exemple și resurse de interes:
www.websocket.org/aboutwebsocket.html
www.websocket.org/demos.html
html5demos.com/web-socket
57. Dr.SabinBuragaprofs.info.uaic.ro/~busaco
Instrumente de programare pentru WebSocket
la nivel de server – independente de limbaj:
deepstream – deepstream.io
Nchan (modul NGINX) – nchan.io
Websocketd – websocketd.com
de considerat și
HornetMQ, Jetty, MigratoryData, websockify
58. Dr.SabinBuragaprofs.info.uaic.ro/~busaco
Instrumente de programare pentru WebSocket
la nivel de server – specifice:
C/C++: Mongoose Embedded Web Server Library,
QtWebSockets, µWebSockets
C#: ASP.NET SignalR, websocket-manager
Java: Atmosphere, Scarlet (pentru Android)
Node.js: Netflux, nodejs-websocket, Socket.IO, SockJS-node
PHP: phpws, Ratchet, Sandstone
Python: Autobahn, Tornado, websockets
Ruby: Faye-websocket
59. Dr.SabinBuragaprofs.info.uaic.ro/~busaco
Instrumente de programare pentru WebSocket
la nivel de client (aplicații) – API-uri/biblioteci:
Arduino WebSocket (C++), Beast (C++),
Java API for WebSocket (JSR 356), libwebsockets (C),
Tyrus (Java), Web-socket-js, clasa WebSocket (Dart),
ZTWebSocket (Objective-C),…
github.com/facundofarias/awesome-websockets
60. Dr.SabinBuragaprofs.info.uaic.ro/~busaco
WebSocket API
navigatorul Web poate fi considerat platformă de
dezvoltare a aplicațiilor Internet
oferă suport și pentru diverse paradigme de comunicare:
RPC (Remote Procedure Call)
+
Pub/Sub (Publish/Subscribe)
vezi WebSub (W3C, 2018) – www.w3.org/TR/websub/
63. Dr.SabinBuragaprofs.info.uaic.ro/~busaco
EventSource API (Server-Send Events)
manieră standardizată de transmitere prin HTTP
a unui flux continuu de date – în format text/event-stream –
de la server spre client (push events)
fără închiderea conexiunii
tratarea recepționării datelor provenite de la server
se realizează via evenimente DOM
65. Dr.SabinBuragaprofs.info.uaic.ro/~busaco
interface EventSource : EventTarget {
constructor (USVString url,
optional EventSourceInit eventSourceInitDict = {});
readonly attribute USVString url;
readonly attribute boolean withCredentials;
// valori ale stării conexiunii
const unsigned short CONNECTING = 0;
const unsigned short OPEN = 1;
const unsigned short CLOSED = 2;
readonly attribute unsigned short readyState;
// evenimente de rețea ce pot fi tratate
attribute EventHandler onopen;
attribute EventHandler onmessage;
attribute EventHandler onerror;
void close ();
};
specificația WebIDL a interfeței
66. Dr.SabinBuragaprofs.info.uaic.ro/~busaco
// instanțiem o sursă de date (un flux)
const flux = new EventSource ("//news.info/web/today");
// tratăm evenimentele
flux.onopen = () => console.log ("Am deschis fluxul");
flux.onmessage = (ev) => console.log ("Date de la server: " + ev.data);
flux.onerror = (ev) => { }; // raportarea erorilor
pentru un exemplu complet, a se studia:
github.com/mdn/dom-examples/tree/master/server-sent-events
69. Dr.SabinBuragaprofs.info.uaic.ro/~busaco
Web Messaging
mesajele pot proveni de la server, via socket-uri Web
sau de la alte documente via canale de comunicație
documentele HTML5 pot transmite date unul altuia,
chiar dacă aparțin unor domenii Internet diferite
mesajele pot conține obiecte
de tip File Blob, FileList, ArrayBuffer etc.
73. Dr.SabinBuragaprofs.info.uaic.ro/~busaco
Broadcast Channel API
permite comunicații simple între contexte de navigare
(ferestre, tab-uri, <iframe>-uri) având aceeași origine
(i.e. pagini ale aceluiași sit Web)
expedierea datelor se face via metoda postMessage ()
recepționarea datelor se realizează
tratând evenimentul onmessage
developer.mozilla.org/Web/API/Broadcast_Channel_API
77. Dr.SabinBuragaprofs.info.uaic.ro/~busaco
Web Workers
conceptul de worker Web:
script rulat în fundal – în accepțiunea daemon-ilor Unix –
independent de alte programe JavaScript
mediul de execuție a unui worker e complet separat,
codul fiind rulat concurent/paralel, în mod asincron
83. Dr.SabinBuragaprofs.info.uaic.ro/~busaco
Web Workers
un obiect WorkerGlobalScope are asociate, de asemenea:
un tip – type (classic sau module)
o adresă – url (inițial, null)
un nume – name (șir de caractere)
o stare a conexiunii HTTPS ("none", "deprecated", "modern")
o politică de securitate (CSP – Content Security Policy)
85. Dr.SabinBuragaprofs.info.uaic.ro/~busaco
[Global=(Worker, DedicatedWorker), Exposed=DedicatedWorker]
interface DedicatedWorkerGlobalScope : WorkerGlobalScope {
[Replaceable] readonly attribute DOMString name; // nume specific
void postMessage (any message, // plasează un mesaj
optional sequence<Transferable> transfer = [ ]);
void postMessage (any message,
optional PostMessageOptions options = {});
void close (); // oprește execuția
// tratează apariția unui mesaj ce poate fi procesat
attribute EventHandler onmessage;
// tratează erorile survenite
attribute EventHandler onmessageerror;
};
“Dedicated web workers are instantiated by
the main process and they can communicate only with it.”
(Guillaume Cedric Marty, 2015)
87. Dr.SabinBuragaprofs.info.uaic.ro/~busaco
<form>
<div>
<label for="number1">Primul număr: </label>
<input type="text" id="number1" value="0">
</div>
<div>
<label for="number2">Al doilea număr: </label>
<input type="text" id="number2" value="0">
</div>
</form>
<p class="result">Rezultatul înmulțirii: 0</p>
…
<!-- programul JS principal care preia valorile numerelor și
le trimite lucrătorului să le proceseze -->
<script src="main.js"></script>
exemplu complet – înmulțirea a două numere:
github.com/mdn/simple-web-worker
88. Dr.SabinBuragaprofs.info.uaic.ro/~busaco
// Program principal care va recurge la un worker pentru procesarea datelor
let nr1 = document.querySelector('#number1'); // preluăm câmpurile din formular
let nr2 = document.querySelector('#number2’);
let rezultat = document.querySelector('.result');
const lucrator = new Worker ("worker.js"); // instanțiem un „lucrător” dedicat
nr1.onchange = function () { // s-a modificat valoarea primului câmp
lucrator.postMessage ([nr1.value, nr2.value]); // se trimit date worker-ului
console.log ('Mesaj expediat lucrătorului');
};
nr2.onchange = function () { // s-a modificat valoarea câmpului al II-lea
lucrator.postMessage ([nr1.value, nr2.value]); // se trimit date
console.log ('Mesaj expediat lucrătorului');
};
lucrator.onmessage = function (ev) { // date primite de la worker
rezultat.textContent = ev.data; // ce vor fi plasate în documentul Web
console.log ('Mesaj primit de la lucrător');
};
89. Dr.SabinBuragaprofs.info.uaic.ro/~busaco
// Codul-sursă al lucrătorului: worker.js
onmessage = (ev) => {
console.log ('Mesaj recepționat de la programul principal');
// datele de la programul principal au fost transmise ca tablou
let rezultat = ev.data[0] * ev.data[1];
if (isNaN (rezultat)) {
console.error ('Parametri incorecți');
postMessage ('Furnizați 2 numere');
} else {
console.log ('Trimitem mesaj cu răspunsul programului principal');
postMessage (`Rezultatul înmulțirii: ${rezultat}`);
}
90. Dr.SabinBuragaprofs.info.uaic.ro/~busaco
Web Workers
shared worker
are un nume ce desemnează cod JavaScript partajabil
poate fi utilizat de toate procesele având (rulând pe)
aceeași origine – tab-uri ale aceleași instanțe de
browser, elemente <iframe> sau alți lucrători partajați –,
comunicând cu acestea
91. Dr.SabinBuragaprofs.info.uaic.ro/~busaco
[Global=(Worker, SharedWorker), Exposed=SharedWorker]
interface SharedWorkerGlobalScope : WorkerGlobalScope {
[Replaceable] readonly attribute DOMString name; // nume specific
void close (); // oprește execuția
// tratarea apariției unei conectări la worker din partea unui client
attribute EventHandler onconnect;
};
un „lucrător” partajat (shared worker)
are asociate o origine și un URL și va recepționa mesaje
via evenimente connect pentru fiecare conexiune în parte
94. Dr.SabinBuragaprofs.info.uaic.ro/~busaco
Web Workers
service worker
“Service workers essentially act as proxy servers that sit
between Web applications, and the browser and the network
(when available). They are intended to (amongst other
things) enable the creation of effective offline experiences,
intercepting network requests, and taking appropriate
action based on whether the network is available, and
updated assets reside on the server.”
developer.mozilla.org/Web/API/Service_Worker_API
98. Dr.SabinBuragaprofs.info.uaic.ro/~busaco
if ('serviceWorker' in navigator) { // există suport disponibil în browser?
// la încărcarea resursei se înregistrează și codul JS de tip service worker
window.addEventListener ('load', () => {
navigator.serviceWorker.register ('/service-worker.js')
.then ( (reg) => { // succes
console.log('ServiceWorker – înregistrat cu succes: ',
reg.scope); // se indică și domeniul de vizibilitate (scope)
}, (eroare) => { // a apărut o eroare… :(
console.log ('ServiceWorker – eroare survenită: ', eroare);
});
});
}
101. Dr.SabinBuragaprofs.info.uaic.ro/~busaco
var url-uriCache = [ // lista adreselor Web
'/', // ale resurselor statice
'/styles/stil.css', // care pot fi stocate în cache
'/scripts/main.js',
'/images/logo.png'
];
this.addEventListener ('install', function (ev) {
ev.waitUntil ( // se așteaptă până când resursele sunt plasate în cache
caches.open ('v1') // prima versiune a cache-ului creat
.then ((cache) => cache.addAll (url-uriCache))
);
});
metode oferite de interfața Cache:
add() addAll() put() match() matchAll() keys() delete()
102. Dr.SabinBuragaprofs.info.uaic.ro/~busaco
Web Workers
service worker
pentru fiecare eveniment fetch recepționat, „lucrătorul”
poate oferi conținutul solicitat (fie din cache,
fie de la distanță – e.g., invocând un serviciu Web)
evenimentul fetch este emis de fiecare dată
când se solicită o resursă aflată sub controlul „lucrătorului”
103. Dr.SabinBuragaprofs.info.uaic.ro/~busaco
// se tratează evenimentul fetch
this.addEventListener ('fetch', (ev) => {
ev.respondWith (
caches.match (ev.request) // resursa solicitată există deja în cache?
.then ( (response) => {
if (response) { // da (cache hit)
return response;
}
return fetch (ev.request); // se execută un fetch() real
}
)
);
});
exemplificări complete:
developer.mozilla.org/Web/API/Service_Worker_API/Using_Service_Workers
developers.google.com/web/fundamentals/primers/service-workers/
112. Dr.SabinBuragaprofs.info.uaic.ro/~busaco
interface Storage {
// mărimea spațiului de stocare
readonly attribute unsigned long length;
// cheie pentru acces la date
DOMString? key (unsigned long index);
// consultarea unui item
getter DOMString getItem (DOMString key);
// asignarea de valori pentru un item
setter creator void setItem (DOMString key, DOMString value);
// eliminarea unui item
deleter void removeItem (DOMString key);
// ștergerea spațiului de stocare
void clear ();
}
metodele setItem () și removeItem ()
se consideră ca fiind atomice
116. Dr.SabinBuragaprofs.info.uaic.ro/~busaco
Web Storage
orice modificare a zonei de stocare
conduce la emiterea evenimentului storage
interface StorageEvent : Event {
readonly attribute DOMString? key;
readonly attribute DOMString? oldValue;
readonly attribute DOMString? newValue;
readonly attribute DOMString url;
readonly attribute Storage? storageArea;
};
117. Dr.SabinBuragaprofs.info.uaic.ro/~busaco
<textarea id="editor" placeholder="Începeți să tastați...">
</textarea>
document.querySelector ('#editor').addEventListener ('keyup',
function (eveniment) { // la fiecare eliberare a tastei…
// stocăm conținutul și data editării
localStorage.setItem ('valoare', this.value);
localStorage.setItem ('data', (new Date ()).getTime ());
}, false);
127. Dr.SabinBuragaprofs.info.uaic.ro/~busaco
Indexed Database API
de asemenea, o înregistrare (record) are o valoare
corespunzătoare unui tip de date ECMAScript
valoarea propriu-zisă e obținută prin evaluarea
așa-numitei căi asociate cheii (key path)
(uzual, un șir de caractere ori șiruri delimitate de „.”)
128. Dr.SabinBuragaprofs.info.uaic.ro/~busaco
interface IDBObjectStore { // specifică maniera de stocare
readonly attribute DOMString name;
readonly attribute DOMString keyPath;
readonly attribute DOMStringList indexNames;
readonly attribute IDBTransaction transaction;
readonly attribute boolean autoIncrement;
IDBRequest put (any value, optional any key); // operații privind cheile
IDBRequest add (any value, optional any key);
IDBRequest delete (any query);
IDBRequest clear ();
IDBRequest get (any query);
IDBRequest getKey (any query);
IDBRequest getAll (optional any query,
optional [EnforceRange] unsigned long count);
IDBRequest getAllKeys (optional any query,
optional [EnforceRange] unsigned long count);
IDBRequest count (optional any query);
129. Dr.SabinBuragaprofs.info.uaic.ro/~busaco
// operații privind cursoarele
IDBRequest openCursor (optional any? query,
optional IDBCursorDirection direction = "next");
IDBRequest openKeyCursor (optional any? query,
optional IDBCursorDirection direction = "next");
// operații vizând indecșii
IDBIndex index (DOMString name);
IDBIndex createIndex (DOMString name,
(DOMString or sequence<DOMString>) keyPath,
optional IDBIndexParameters options);
void deleteIndex (DOMString indexName);
};
dictionary IDBIndexParameters { // folosit pentru precizarea opțiunilor
boolean unique = false;
boolean multiEntry = false;
};
130. Dr.SabinBuragaprofs.info.uaic.ro/~busaco
[Exposed=(Window, Worker)]
interface IDBRequest : EventTarget { // modelează o cerere
readonly attribute any result; // rezultatul interogării emise
readonly attribute DOMException? error; // eventuala eroare survenită
readonly attribute (IDBObjectStore or IDBIndex or IDBCursor)? source;
readonly attribute IDBTransaction? transaction;
// starea interogării: în așteptare ("pending") sau efectuată ("done")
readonly attribute IDBRequestReadyState readyState;
attribute EventHandler onsuccess; // funcții de tratare a evenim.
attribute EventHandler onerror;
};
alte detalii:
developer.mozilla.org/Web/API/IDBRequest
131. Dr.SabinBuragaprofs.info.uaic.ro/~busaco
Indexed Database API
accesul la înregistrări se poate realiza și via indecși
specificați de interfața IDBIndex
metode utile:
get() getKey() getAll() getAllKeys()
count()
openCursor() openKeyCursor()
developer.mozilla.org/Web/API/IDBIndex
136. Dr.SabinBuragaprofs.info.uaic.ro/~busaco
[Exposed=(Window, Worker)]
interface IDBCursor {
readonly attribute (IDBObjectStore or IDBIndex) source; // sursa datelor
readonly attribute IDBCursorDirection direction; // direcția de iterare
readonly attribute any key; // cheia
readonly attribute any primaryKey; // cheia primară
IDBRequest update (any value); // actualizarea valorilor
IDBRequest delete ();
void advance ([EnforceRange] unsigned long count);
void continue (optional any key);
void continuePrimaryKey (any key, any primaryKey);
};
developer.mozilla.org/Web/API/IDBCursor
137. Dr.SabinBuragaprofs.info.uaic.ro/~busaco
Indexed Database API
excepții specifice:
UnknownError ConstraintError DataError
TransactionInactiveError ReadOnlyError VersionError
excepții preluate de la DOM:
NotFoundError InvalidStateError InvalidAccessError
AbortError TimeoutError QuotaExceededError
SyntaxError DataCloneError
138. Dr.SabinBuragaprofs.info.uaic.ro/~busaco
Indexed Database API
pentru detalii și exemplificări, a se experimenta:
developer.mozilla.org/Web/API/IndexedDB_API/Using_IndexedDB
gist.github.com/JamesMessinger/a0d6389a5d0e3a24814b
exemple specifice vizând PWA
(Progressive Web Applications)
developers.google.com/web/ilt/pwa/working-with-indexeddb
www.smashingmagazine.com/2018/11/guide-pwa-progressive-web-applications/
detalii într-un
curs viitor
141. Dr.SabinBuragaprofs.info.uaic.ro/~busaco
<script> new Worker('actualizator.js'); </script>
var server = new WebSocket('ws://whatwg.org/database'); // conexiunea cu
var db = openDatabase('demo', '1.0', 'Date demo', 10240); // baza de date
server.onmessage = function (eveniment) {
// datele sunt în format "comanda cheie valoare" (comanda e "+" sau "-")
var date = eveniment.data.split(' ');
switch (date[0]) {
// operația de inserare a unei valori pe baza cheii
case '+': db.transaction (function (t) {
t.executeSql ('INSERT INTO informatii (cheie, valoare) VALUES (?, ?)',
date[1], date[2]); });
// operația de ștergere
case '-': db.transaction (function (t) {
t.executeSql ('DELETE FROM informatii
WHERE cheie=? AND valoare=?', date[1], date[2]); });
}
};
un worker ce efectuează operații asupra
unei baze de date existente la nivel de client
144. Dr.SabinBuragaprofs.info.uaic.ro/~busaco
File API
interfețe de interes:
File – consultarea informațiilor vizând un fișier
Blob – consultarea datelor binare imutabile
FileList – lista unor fișiere, eventual via <input type="file">
FileReader – citirea datelor dintr-un File sau Blob
API-ul se poate folosi în conjuncție cu
XMLHttpRequest, postMessage, drag & drop, WebWorker,…
145. Dr.SabinBuragaprofs.info.uaic.ro/~busaco
interface FileReader : EventTarget {
// metode de citire asincronă
void readAsArrayBuffer (Blob blob);
void readAsBinaryString (Blob blob);
void readAsText (Blob blob, optional DOMString encoding);
void readAsDataURL (Blob blob);
void abort ();
// coduri de stare
const unsigned short EMPTY = 0;
const unsigned short LOADING = 1;
const unsigned short DONE = 2;
readonly attribute unsigned short readyState;
// rezultatul obținut: File sau Blob
readonly attribute (DOMString or ArrayBuffer)? result;
146. Dr.SabinBuragaprofs.info.uaic.ro/~busaco
interface FileReader : EventTarget {
// metode de citire asincronă
void readAsArrayBuffer (Blob blob);
void readAsBinaryString (Blob blob);
void readAsText (Blob blob, optional DOMString encoding);
void readAsDataURL (Blob blob);
void abort ();
// coduri de stare
const unsigned short EMPTY = 0;
const unsigned short LOADING = 1;
const unsigned short DONE = 2;
readonly attribute unsigned short readyState;
// rezultatul obținut: File sau Blob
readonly attribute (DOMString or ArrayBuffer)? result;
evenimente ce pot fi tratate:
onloadstart onprogress onload onabort onerror onloadend
148. Dr.SabinBuragaprofs.info.uaic.ro/~busaco
Privire de ansamblu
asupra stocării la nivel de client
Web Storage API: localStorage + sessionStorage
IndexedDB
Web SQL – specificație abandonată
Application Cache – via Service Worker
File APIs
cookie-uri clasice
inițiative neoficiale:
File & Directory Entries API și Cookie Store API
149. Dr.SabinBuragaprofs.info.uaic.ro/~busaco
Alte inițiative – unele neoficiale:
acces la elementele sistemului de fișiere
File and Directory Entries API (30 septembrie 2019)
wicg.github.io/entries-api/
acces asincron la datele stocate de cookie-uri
Cookie Store API (02 decembrie 2019)
wicg.github.io/cookie-store/
partajarea conținutului curent la o destinație specifică
Web Share API (06 noiembrie 2019)
w3c.github.io/web-share/