Tehnici Web

Ajax

Claudia Chiriță . 2023/2024

Obiecte

  • un obiect este o colecție de perechi proprietate-valoare
  • daca valoarea este o funcție, atunci proprietatea se numește metodă
  • var ob = {prop1: val1, prop2: val2, ... , propn: valn};
  • accesarea proprietăților:
    ob.prop1; // val1
    ob["prop1"]; // val1
    

Prototipuri

  • prototipul unui obiect este desemnat prin
    obiect.prototype
  • orice obiect moștenește proprietățile obiectului prototip (prototypal inheritance)
  • obiectele care au același prototip formează o clasă
  • toate obiectele sunt descendenți ai obiectului generic Object
Object.getPrototypeOf() // prototipul obiectului specificat

Crearea obiectelor

  • prin object literal
  • proprietățile, metodele, împreună cu valorile lor sunt enumerate între acolade
  • se creează un singur obiect
var cat = {nume:"Tigger", culoare:"neagră", vârstă:14}

Crearea obiectelor

  • cu ajutorul obiectului generic
  • se apelează constructorul new Object() și se adaugă apoi proprietățile și metodele
  • se creează un singur obiect
var cat = new Object(); 
cat.nume = "Tigger";
cat.culoare = "neagră";
cat.vârstă = 14;

Crearea obiectelor

  • cu ajutorul unui constructor de obiecte
  • se definește o funcție constructor(param) care apoi va fi apelată cu new constructor(param) pentru fiecare obiect care va fi creat
function cat(n, c, v) { 
  this.nume = n;
  this.culoare = c;
  this.vârstă = v;
}

var c1 = new cat("Tigger", "neagră", 14);
var c2 = new cat("Fluff", "albă", 2);

Crearea obiectelor

  • cu metoda Object.create()
  • Object.create(ob)
    creează un nou obiect, folosind un obiect existent ob ca prototip al obiectului nou creat

Exemplu: Interval

var interval = {
  mx: 2,
  my: 4,
  apartine: function(z) {
    return (z <= this.my) && (z >= this.mx);
  }
}; // clasa

var obi = Object.create(interval); 
// obiect din clasa interval
obi.mx = 5;
obi.my = 7; // suprascriem proprietățile prototipului        

Exemplu: Interval

var intervalD = Object.create(interval);
intervalD.apartine = function(z) {
  return (z < this.my) && (z > this.mx);
}; // subclasa

var obid = Object.create(intervalD);
obid.mx = 5;
obid.my = 10;    

Exemplu: Interval

interval.valid = function() {
  return (this.my >= this.mx);
};

intervalD.vid = function() {
  return (this.mx == this.my);
};

alert(obid.valid()); // true
alert(obid.vid());  // false

cuvântul-cheie this

  • în interiorul unui constructor sau al unei metode asociate unui obiect, this se referă la obiectul curent
  • într-o funcție folosită ca event handler, se referă la elementul pentru care este definit listenerul
  • altfel, this se referă la obiectul window

Exemplu: Interval (2)

function Interval(x, y) {
  this.mx = x;
  this.my = y;
} // clasa

Interval.prototype.apartine = function(z) {
  return (z <= this.my) && (z >= this.mx);
} /* metodă adaugată în prototipul obiectelor 
     create cu funcția constructor */

Exemplu: Interval (2)

var obi = new Interval(1, 4); // obiect din clasa Interval

Interval.prototype.valid = function() {
  return (this.my >= this.mx);
};

alert(obi.valid()); // true

Exemplu: Interval (2)

prototype

Exemplu: Interval (2)

definirea subclaselor

function IntervalD(x, y) {
  Interval.call(this, x, y);
} // this este obiectul care se construiește

IntervalD.prototype = Object.create(Interval.prototype);
// schimbăm prototipul obiectelor create cu IntervalD
IntervalD.prototype.constructor = IntervalD; 
// restaurăm proprietatea constructor

IntervalD.prototype.apartine = function(z) {
  return (z < this.my) && (z > this.mx);
};

var obid = new IntervalD(5, 10);

Exemplu: Interval (2)

definirea subclaselor

function IntervalD(x, y) {
  Interval.call(this, x, y);
} 
IntervalD.prototype = Object.create(Interval.prototype);
IntervalD.prototype.constructor = IntervalD; 

IntervalD.prototype.apartine = function(z) {
  return (z < this.my) && (z > this.mx);
};
IntervalD.prototype.valid = function() {
  return (Interval.valid.call(this) && (this.mx != this.my));
}

XML

Extensible Markup Language

XML

  • limbaj de marcare similar cu HTML
  • nu conține taguri predefinite, utilizatorul își definește propriile taguri și structura documentului
  • conceput pentru stocarea și transmiterea datelor
  • independent de software și hardware
  • utilizat pentru a crea limbaje de marcare precum XHTML, SVG, MathML

Structura unui document XML

  • Un document XML este format din:
    • elemente: taguri <nume_tag>
      case sensitive
    • date caracter: conținutul elementelor

Structura unui document XML

  • se definește versiunea XML și codificarea caracterelor (prima linie în document)
    <?xml version="1.0" encoding="UTF-8"?>
  • document XML: structură arborescentă
  • toate documentele XML trebuie să conțină un element rădăcină (root)
    
      
        ...
      
    

Sintaxa XML

  • există un singur element root într-un document XML
  • fiecare element trebuie să aibă tag de închidere
  • elementele XML trebuie să fie corect imbricate
  • atributele asociate elementelor nu pot conține mai multe valori

Entități

  • pentru a ne referi la caractere rezervate

Exemplu

<?xml version="1.0" encoding="UTF-8"?>
 // elementul rădăcină
    // element copil
      Piranesi
      Susanna Clarke
      2020
      30.00
    
    
       Klara and the Sun
       Kazuo Ishiguro
       2021
       29.99
    

XMl-Parser

  • browserele au un analizor XML încorporat pentru a accesa și manipula documente XML
  • înainte ca un document XML să poată fi accesat, acesta trebuie convertit într-un obiect XML DOM

XMl-Parser

  • XML DOM defineste proprietăți și metode pentru accesarea și editarea XML
    • proprietăți: nodeName, nodeValue, parentNode, childNodes, attributes
    • metode: getElementsByTagName(), appendChild(), removeChild()

XMl-Parser

text = "" +"Piranesi" +
"Susanna Clarke" +"2020" +
""; // XML ca string

parser = new DOMParser(); // se creează un analizor XML DOM

xmlDoc = parser.parseFromString(text,"text/xml"); 
// se creează un obiect XML DOM din stringul text

xmlDoc.getElementsByTagName("title")[0].childNodes[0].nodeValue;
// extragem informația din nodurile XML DOM

JSON

JavaScript Object Notation

JSON

  • oferă o modalitate de reprezentare a datelor, ca alternativă la XML
  • bazat pe JavaScript; în prezent un format independent de limbaj
  • multe limbaje pot prelucra date în format JSON
  • folosit pentru schimbul de informații cu serverul

JSON

elemente de bază:

Object: {"cheie1":val1, "cheie2":val2}
Array: [val1, val2, val3]
Value: string, number, object, array, true, false, null
date.json
[{"pers": {"nume":"Klara", "varsta":12} },
 {"pers": {"nume":"Josie", "varsta":14} } ]

Sintaxa JSON

  • câmpul cheie trebuie să fie scris cu ghilimele
    "nume":"Klara"
  • câmpul valoare poate fi:
    string, number, obiect (JSON), array, boolean, null
    nu poate fi function, date, undefined
  • obiectele JSON sunt reprezentate între acolade
    {"nume":"Klara", "varsta":12, "porecla":"Robo"}

Exemplu JSON


JSON String:	{ "nume":"Klara" }
JSON Number:	{ "varsta":12 }
JSON Object:	{ "pers": { "nume":"Josie", "varsta":14 } }
JSON Array:		{ "copii": [ "Klara", "Josie", "Rick" ] }
JSON Boolean:	{ "robot": true }
JSON null:		{ "porecla": null }
        

Obiecte JSON

myObj = { "cheie1":val1, "cheie2":val2, "cheie3":val3 }
  • accesarea obiectelor:
    myObj.cheie1
    
    myObj["cheie1"] 

Obiecte JSON

  • iterarea proprietăților unui obiect:
    var myObj = { "copil":"Klara", "varsta":12, "robot":true };
    for (x in myObj) {
       document.getElementById("prop").innerHTML += x + "
    "; }
    <p id="prop"></p>
    paragraful va conține:
    copil
    varsta
    robot

Obiecte JSON

  • iterarea proprietăților unui obiect:
    var myObj = { "copil":"Klara", "varsta":12, "robot":true };
    for (x in myObj) {
       document.getElementById("val").innerHTML += myObj[x]+ " ";
    }
    <p id="prop"></p>
    paragraful va conține: Klara 12 true

Obiecte JSON încorporate

myObj = { "nume":"Klara",
          "varsta":12, 
          "componente": {"baterie:"solara", "motoare":"10"} }
  • accesarea obiectelor încorporate:
    myObj.componente.motoare // 10
            
    myObj.componente["motoare"] // 10

Obiecte JSON încorporate

myObj = { "nume":"Klara",
          "varsta":12, 
          "componente": {"baterie":"solara", "motoare":"10"} }
  • modificarea valorilor proprietăților:
    myObj.componente.motoare="11";
  • ștergerea proprietăților:
    delete myObj.componente.baterie;

JSON Arrays

[val1, val2, ...., valn]
val1,...,valn pot fi string, number, object, array, boolean, null
  • Array în interiorul obiectelor JSON
    myObj = { "nume":"Klara",
              "varsta":12, 
              "componente": ["baterie", "motoare", "senzori"} }
    accesarea valorilor:
    myObj.componente[0] // baterie

JSON Arrays

  • Array în interiorul obiectelor JSON
    myObj = { "nume":"Klara",
              "varsta":12, 
              "componente": ["baterie", "motoare", "senzori"] }
    iterarea valorilor în Array:
    for (i in ob.componente){ x += ob.componente[i]; }
    
    for (i = 0; i < ob.componente.length; i++) {
       x += ob.componente[i];
    }          

Obiectul JSON în JavaScript

JSON.stringify(valoare) 
// transformă un obiect JavaScript într-un string JSON

JSON.parse(text)
 // transformă un string JSON într-un obiect JavaScript 

poate fi folosit pentru memorare în
localStorage și sessionStorage

Obiectul JSON în JavaScript

var o1 = {copil: {nume:"Klara", varsta:12}},
    o2 = {copil: {nume:"Josie", varsta:14}},
    o = [o1,o2];

var s = JSON.stringify(o);
// "[{"copil":{"nume":"Klara","varsta":12}},{"copil":{"nume":"Josie","varsta":14}}]"

localStorage.setItem("myarray", s);
var st = localStorage.getItem("myarray");

var jo = JSON.parse(st);

AJAX

Asynchronous JavaScript and XML

AJAX

  • termenul AJAX a fost introdus de Jesse James Garrett în 2005
  • azi se referă la un grup de tehnologii folosite pentru procesele client ce descarcă informație de la server fără reîncărcarea completă a unei pagini web
  • inițial se foloseau documente XML pentru request-uri și response-uri
  • acum formatul JSON e mult mai uzual

AJAX

  • permite actualizarea unor părți ale unei pagini web fără reîncărcarea completă a paginii
  • trimite cereri către un server web și citește datele primite de la server
  • nucleul său îl reprezintă obiectul XMLHttpRequest care este folosit pentru a schimba date asincron cu serverul web

AJAX

ajax

XMLHttpRequest

  • obiect JavaScript ce permite trimiterea de cereri către un server și primirea rezultatului în script
  • pot fi procesate în paralel mai multe conexiuni cu serverul, fără blocarea browser-ului până la primirea răspunsului
  • înainte de utilizarea XMLHttpRequest, trebuie creată o instanță
    var xhr = new XMLHttpRequest()

XMLHttpRequest

  • pune la dispoziție mai multe proprietăți și metode pentru comunicarea client/server
open() // creează cererea
send() // trimite cererea

readyState // starea cererii (0,1,2,3,4)
onreadystatechange 
// funcția care se execută la schimbarea stării cererii

status // codul de stare HTTP (200 OK)
responseText
// răspunsul primit de la server în format text
responseXML 
// răspunsul primit de la server în format XML
	

cereri HTTP

open( method, url, async ) // specifică tipul de cerere
/* method: poate fi GET sau POST
   url: adresa serverului
   async: true (asynchronous) sau false (synchronous) */
send() // trimite cererea către server ( GET )
send(date) // trimite cererea către server ( POST )
var xhr = new XMLHttpRequest();
xhr.open("GET", "http://localhost:3000/test.txt", true);
xhr.send();

Gestionarea răspunsului

  • proprietatea readyState reprezintă starea cererii:
    1. cererea este neinițializată
    2. conexiune stabilită cu serverul
    3. cererea a fost primită
    4. se procesează cererea
    5. cererea este finalizată și răspunsul este gata
  • proprietatea onreadystatechange definește o funcție care trebuie executată când se schimbă readyState
    xhr.onreadystatechange = nume-functie;
    

Gestionarea răspunsului

  • proprietatea status: codul de stare HTTP al răspunsului de la server, în format numeric
    (200 "OK", 403 "Forbidden", 404 "Not found")
  • proprietatea statusText: statusul în format text ("OK", "Not Found")

Gestionarea răspunsului

  • proprietatea responseText: returnează răspunsul primit de la server, în format text (string)
  • proprietatea responseXML: returnează răspunsul primit de la server, în format XML

Exemplu - TEXT

Gestionarea răspunsului

  • Obiectul XML DOM în JavaScript poate fi parcurs cu metode asemănătoare celor din DOM
<?xml version="1.0" encoding="UTF-8"?>
 
   
   
 
var xml = httpRequest.responseXML;
var vpers= xml.getElementsByTagName('pers');
alert(vpers[0].getAttribute('nume'));

Exemplu - XML

Exemplu - JSON

Trimiterea formularelor

Trimiterea formularelor via JS

cu JSON?

Trimiterea formularelor via JS

cu FormData

ASYNC JAVASCRIPT

ASYNC JAVASCRIPT

  • sync vs. async programs
  • event handlers sunt un tip de programare asincronă: apelăm o funcție (handlerul) nu imediat, ci când se declanșează un eveniment
    event -> încheierea operației asincrone
  • XMLHttpRequest - API asincron bazat pe evenimente: adăugăm event listenere obiectului XMLHttpRequest

ASYNC JAVASCRIPT

Callbacks

  • un event handler e un tip particular de callback
  • callback = funcție transmisă unei alte funcții ca parametru, în vederea apelării ei la momentul potrivit
  • callbacks în callbacks = callback hell sau pyramid of doom
  • API-urile asincrone moderne nu folosesc callbacks

Promises

  • cod producător: de obicei necesită mult timp și întoarce un rezultat (ex: ia date dintr-o bază de date)
  • cod consumator: dorește rezultatul codului producător de îndată ce este gata
  • promise: obiect JavaScript care leagă codul producător și codul consumator

Promises

  • promise: obiect returnat de o funcție asincronă, ce reprezintă starea curentă a operației executate
  • la momentul returnării promisiunii în funcția caller, de regulă operația nu s-a terminat; obiectul oferă însă metode pentru gestiunea succesului sau eșescului operației

Promises

crearea unei promisiuni
promise = new Promise( function(resolve, reject) {
  /* cod producător care se execută asincron:
     setInterval, setTimeout, cereri Ajax, evenimente */
  resolve(value) // pentru succes
  reject(error) // pentru eroare
} );

Promises

  • la crearea unei promisiuni, se apelează automat funcția transmisă ca argument promisiunii (numită funcție executor)
  • executorul are ca parametri două funcții predefinite (resolve & reject) și conține codul producător care ar trebui să producă în cele din urmă rezultatul dorit

Promises

  • în funcție de rezultatul obținut (codul asincron va decide dacă e cu succes sau eșec) se va apela una din cele două funcții (functia de succes - resolve sau funcția de eșec - reject)
  • un obiect promise se poate afla într-una din stările: pending (în așteptare), fulfilled (îndeplinită), rejected (respinsă)

Promises

promises

Promises

// cod consumator care așteaptă rezultatul
promise.then(function (value) { /* cod pentru succes */ },
             function(error)  { /* cod pentru eroare */ })
       .catch(function(error) { /* tratarea erorii */ })
  • funcțiile consumatoare pot fi înregistrate folosind metodele .then, .catch și .final

Promises

  • primul argument al lui .then este o funcție care rulează atunci când promisiunea este rezolvată și primește rezultatul așteptat
  • al doilea argument al lui .then este o funcție care rulează atunci când promisiunea este respinsă și primește eroarea

Promises

Fetch

const promise = fetch(url, [options]);
/* întoarce o promisiune folosită pentru a obține 
   răspunsul de la server
   
   url: adresa url a severului
   options: method, headears, body (opționale) */     

Fetch

const promise = fetch(url, [options]);
promise.then(function(response) {
               return response.text();
             });       
  • promisiunea returnată de fetch() este rezolvată cu un obiect din clasa Response imediat ce serverul răspunde cu un header
  • promisiunea este respinsă dacă cererea HTTP nu poate fi trimisă (există probleme de conexiune) sau nu se primește răspunsul

Fetch

cerere Ajax cu XMLHttpRequest

Fetch

cerere Ajax cu Fetch

Trimiterea formularelor via Fetch

                      /~\  
                     (O O)                  
                     _\=/_       întrebări?                  
                    /  _  \                         
                   //|/.\|\\                        
                  ||  \_/  ||                       
                  || |\ /| ||                       
                   # \_ _/ #                        
                     | | |                          
                     | | |                          
                     []|[]                          
                     | | |                          
                    /_] [_\