jquery ajax obține date din alt domeniu. Ajax pe mai multe domenii cu jQuery

2 decembrie , 2016

Am scris odată un articol despre cum să creez widget-uri încorporabile în javascript nativ și php. Și totul ar fi bine, dar un moment nu a fost atins în el. Puteți utiliza astfel de widget-uri pe propriul site, dar este mai interesant să le creați pentru resurse terțe. Dar în acest caz, browserul trebuie să încarce datele necesare dintr-un alt domeniu - acestea sunt solicitări ajax între domenii.

Din punctul de vedere al programatorilor front-end, interogările între domenii nu sunt diferite de cele obișnuite. Dar pe partea din spate este o diferență. De ce nu totul este atât de simplu cu ele și cum să le implementați - citiți despre asta în articol.

Încercarea de a obține date de pe alt domeniu

Pentru simplitate, luați în considerare obținerea cererilor. Să presupunem că există un fișier html pe server, pe care trebuie să îl încărcăm cu ajax dintr-un alt domeniu ..html. Deschideți-l și asigurați-vă că este disponibil efectiv - (se deschide într-o filă nouă). Este un div normal cu textul „conținut din template.html”.

Și acum să obținem acest html ajax direct din consola browserului.

Să nu ne deranjez cu javascriptul nativ, ci să tragem cererea folosind jQuery.get() și să trimitem în consolă ceea ce am primit ca răspuns de la server.

$..html", function(responce) (console.log(responce)));

Deschideți instrumentele pentru dezvoltatori chiar acum în browser și rulați această interogare în fila consolă.

Veți vedea așa ceva

Totul este în regulă, a trimis o cerere, a primit un răspuns. S-ar părea, ce ar putea fi mai ușor? Acum accesați orice alt site unde este inclus jQuery și încercați să faceți același lucru. Doar nu pe site-ul https, de ce - veți afla la sfârșitul articolului.

De exemplu, am verificat cereri pe site-ul de fotbal bombardir.ru. Și, în același timp, m-am întrebat ce fel de gunoi nu cade în consolă chiar și pe astfel de site-uri destul de cunoscute. Cu toate acestea, conversația nu este despre asta.

Rulați o solicitare din alt domeniu și veți vedea o imagine nu tocmai bună în consolă. El spune că este imposibil de descărcat, nu există date și, în general, tristețe.

Dacă deschideți fila Rețea și găsiți acolo cererea corespunzătoare, veți vedea că serverul chiar ne-a returnat 200 OK
Nu există conținut de fișier. Care e siretlicul?

Ce a mers prost și care va fi soluția

Problema este că politica de internet nu permite browserelor să extragă date din nicio resursă. Cu excepția cazului în care aceste resurse în sine sunt interesate să distribuie date specifice.
Cazul nostru este doar atat. Pentru a acorda permisiunea de a utiliza fișierul html de oriunde, trebuie să trimiteți antetul http Access-Control-Allow-Origin atunci când solicitați acest fișier: *

Acum întrebarea este cum se face. Dacă dumneavoastră (sau administratorii) aveți acces la nginx, atunci o modalitate este să configurați acest antet pentru a fi transmis prin serverul web. Mergeți la admini cu o solicitare corespunzătoare sau căutați pe Google configurațiile necesare pentru serverul dvs. web.

Dacă acest acces nu este disponibil, ca, de exemplu, cu aproape orice furnizor de găzduire la un preț ieftin, atunci trebuie să ieși pe cont propriu. Și aici php vine în ajutor. Ideea este să aruncăm html-ul nostru într-un fișier php, care va trece titlul și va oferi conținutul dorit.

Se va dovedi așa, creați un fișier template.php și scrieți comanda php în prima linie

Antet ("Acces-Control-Allow-Origin: *");

Conținut din template.php

Adică conținutul template.php va fi așa, nu uitați de întrebările și parantezele php

Fișierul de pe webdevkin este creat și se află (se deschide într-o filă nouă). Să încercăm acum să-l solicităm de la alt domeniu și să vedem ce se întâmplă

$..php", function(responce) (console.log(responce)));

După cum puteți vedea, totul funcționează bine - fișierul este încărcat!

Să ne uităm la fila Rețea.
Vă rugăm să rețineți că antetul Access-Control-Allow-Origin care ne interesează a apărut în blocul Response Headers: *

În general, articolul este terminat. Rămâne să adunați gânduri într-o grămadă și să adăugați puțin mai multe informații.

Rezumat și rezumat

  • 1. Nu puteți solicita prin ajax orice resursă dintr-un alt domeniu
  • 2. Trimiteți antetul Access-Control-Allow-Origin pentru toate resursele care trebuie accesate de oriunde
  • 3. Fă-o cu un server web sau php
  • 4. Acest antet este trimis la php prin antetul comenzii ("Access-Control-Allow-Origin: *")
  • 5. Access-Control-Allow-Origin: * - permite accesul la toate domeniile, Access-Control-Allow-Origin: site.ru - numai la domeniul site.ru
  • 6. Access-Control-Allow-Origin este trimis chiar la începutul fișierului php, chiar înainte de ieșirea altor date (precum și orice alte anteturi http)
  • 7. O „resursă” nu este doar un fișier cu marcaj html, ci și orice adresă URL la care se adresează o solicitare ajax, de exemplu, obținerea de date json sau o solicitare post pentru a adăuga un rând la tabelul bazei de date

Iar ultimul, livrat separat. Nu degeaba am cerut să execut cereri de pe site-ul http. Cu https, nu va fi posibilă încărcarea datelor de pe http din alt motiv - conținut mixt. Și site-ul este încă http-site ( la curent: nu mai, am mutat site-ul pe https)

Acesta este ceea ce veți vedea în consolă atunci când încercați să faceți aceeași cerere de pe orice site https. Prin urmare, dacă aveți de-a face cu widget-uri încorporabile sau ceva de genul acesta, cu siguranță trebuie să puneți un certificat ssl pe site-ul dvs.

jQuery.ajax() - face o cerere către server fără a reîncărca pagina. Aceasta este o metodă de nivel scăzut care are cantitate mare setări. Acesta stă la baza tuturor ajax-ului, care este adesea mai ușor de înțeles și de utilizat, dar oferă încă o funcționalitate limitată în comparație cu această metodă.

$.ajax() returnează un obiect XMLHttpRequest. În cele mai multe cazuri, nu va trebui să lucrați direct cu acest obiect, dar este încă disponibil în cazul în care trebuie să anulați manual cererea.

Argumentul funcției $.ajax() este un obiect format din perechi cheie/valoare care sunt folosite pentru a inițializa și gestiona cererea.

Solicitarea Ajax are două cazuri de utilizare:

jQuery.ajax(url[, setări])

Singura diferență față de versiunea anterioară a metodei este că proprietatea URL de aici face parte din setări și nu este un parametru separat.

Lista setărilor

  1. acceptă(implicit: depinde de DataType)
    Tip: obiect.
    Când se face o solicitare, anteturile indică tipurile de conținut permise așteptate de la server. Valorile acestor tipuri vor fi preluate din parametrul accepts. De exemplu, următorul exemplu specifică tipurile personalizate valide:

    $.ajax(( acceptă: ( mycustomtype: "application/x-some-custom-type"), convertoare: ( "text mycustomtype": function(result) ( return newresult; ) ), dataType: "mycustomtype" ));

    $ . ajax((

    accepta :(

    mycustomtype: „aplicație/x-some-custom-type”

    convertoare :(

    „text mycustomtype” : funcție (rezultat) (

    returnează un nou rezultat;

    dataType: „mycustomtype”

    } ) ;

  2. asincron(implicit: adevărat)
    Tip: valoare booleană.
    În mod implicit, toate cererile sunt trimise asincron (adică după trimiterea unei cereri către server, pagina nu își oprește activitatea în așteptarea unui răspuns). Dacă trebuie să trimiteți cereri sincron, setați această opțiune la fals. Solicitările pe mai multe domenii și solicitările de tip „jsonp” nu pot fi executate în modul sincron. Rețineți că solicitările sincrone pot bloca browserul pe durata solicitării.
  3. beforeSend(jqXHR, setări)
    Tip: functie.
    Conține o funcție care va fi apelată chiar înainte ca o solicitare ajax să fie trimisă către server. O astfel de funcție poate fi utilă pentru modificarea obiectului jqXHR (în versiuni timpurii biblioteci (înainte de 1.5), XMLHttpRequest este folosit în loc de jqXHR). De exemplu, puteți modifica / specifica anteturile dorite (anteturi), etc. Obiectul jqXHR va fi transmis funcției ca prim argument. Al doilea argument este setările cererii.
    beforeSend este legat de evenimentele ajax. Prin urmare, dacă funcția specificată în ea returnează false, cererea ajax va fi anulată.Începând cu jQuery-1.5, beforeSend este apelat indiferent de tipul cererii.
  4. cache(implicit: true, false pentru dataType „script” și „jsonp”)
    Tip: valoare booleană.
    dacă doriți ca browserul să nu memoreze în cache cererea făcută, atunci setați acest parametru la false. Vă rugăm să rețineți că, dacă parametrul este setat la false, atunci șirul „_=" va fi adăugat la adresa URL.
  5. complete(jqXHR, textStatus)
    Tip: functie.
    O funcție care este executată de fiecare dată când se finalizează o solicitare AJAX (după finalizarea succesului și a erorii). Doi parametri sunt trecuți funcției: jqXHR (în versiunile anterioare ale bibliotecii (înainte de 1.5), XMLHttpRequest este folosit în loc de jqXHR) și starea solicitării (valoarea șirului: „succes”, „notmodified”, „error”, „timeout”, „abort” sau „parsererror”).
    Începând cu jQuery-1.5, puteți trece o matrice de funcții în loc de o singură funcție la parametrul complet. Toate funcțiile vor fi apelate în ordinea în care sunt date în această matrice.
  6. continuturi
    Tip: obiect.
    Parametru introdus în jQuery-1.5 Specificat de un obiect în format (string:regex) și determină modul în care jQuery va analiza (parsa) răspunsul de la server, în funcție de tipul acestuia.
  7. tipul de conținut
    Tip: boolean sau șir.
    La trimiterea unei cereri către server, datele sunt transmise în formatul specificat în contentType. Valoarea implicită este „application/x-www-form-urlencoded; charset=UTF-8' care este bine în majoritatea cazurilor. Dacă specificați acest parametru în mod explicit, atunci acesta va fi transmis serverului (chiar dacă nu au fost trimise date acolo).
    Începând cu jQuery-1.6, puteți trece false pentru a nu seta titlul.
  8. context
    Tip: obiect.
    Obiectul care va deveni context după executarea cererii (valoarea transmisă variabilei this). De exemplu, dacă specificați un element DOM ca context, atunci toți gestionanții de solicitare ajax vor fi, de asemenea, executați în contextul acestui element DOM. În acest exemplu cuvânt cheie acesta va conține document.body:

    $.ajax(( url: "test.html", context: document.body )).done(function() ( $(this).addClass("terminat"); ));

    $ . ajax((

    url: "test.html" ,

    context: document. corp

    ) ) . terminat(funcție()(

    $(acest) . addClass("terminat");

    } ) ;

  9. convertoare(implicit: ("* text": window.String, "text html": true, "text json": jQuery.parseJSON, "text xml": jQuery.parseXML))
    Tip: obiect.
    Parametrul introdus în jQuery-1.5 Determină ce funcții vor fi folosite pentru a converti valorile de la un tip la altul.
  10. între domenii(implicit: false pentru același domeniu, adevărat pentru solicitările pe mai multe domenii)
    Tip: valoare booleană.
    Această opțiune a fost introdusă în jQuery-1.5 Dacă doriți să executați o solicitare între domenii (cum ar fi JSONP) pe același domeniu, setați setarea crossDomain la true. Acest lucru permite, de exemplu, să faceți redirecționări de server către un alt domeniu.
  11. date
    Tip: obiect, șir sau matrice.
    Datele care urmează să fie trimise către server. Dacă datele nu sunt un șir, atunci sunt convertite într-un șir de interogare. Pentru solicitările GET, datele sunt atașate la adresa URL. Obiectul trebuie să fie format din perechi cheie/valoare. Dacă valoarea este o matrice, jQuery aranjează valorile pe baza setărilor tradiționale. În mod implicit, de exemplu, (foo:["bar1", "bar2"]) devine &foo=bar1&foo=bar2 .
  12. dataFilter(date, tip)
    Tip: functie.
    Funcția care va îndeplini preprocesare datele trimise de server, de ex. ar trebui să joace rolul unui filtru și să returneze un șir curățat. La această funcție sunt trecuți doi parametri: datele menționate și valoarea parametrului dataType. Funcția specificată în dataFilter trebuie să returneze datele procesate.
  13. dataType(implicit: detectat automat (xml, json, script sau html))
    Tip: sfoară.
    Tipul de date în care este așteptat răspunsul de la server. Dacă nu este setat, jQuery va încerca să o determine automat folosind MIME-ul primit de la server.
  14. eroare
    Tip: functie
    Funcția care trebuie apelată dacă cererea către server eșuează. Este prevăzut cu trei parametri: jqXHR (înainte de 1.5, se folosește XMLHttpRequest), un șir care descrie eroarea care a apărut și un obiect excepție dacă s-a întâmplat. Valorile posibile pentru al doilea argument sunt „timeout”, „error”, „notmodified” și „parsererror” (în cazuri neașteptate, poate fi returnat null). Începând cu jQuery-1.5, acest parametru poate lua fie o singură funcție, fie o matrice de funcții.
    Evenimentul de eroare nu are loc atunci când dataType este script sau JSONP.
  15. global(implicit: adevărat)
    Tip: valoare booleană.
    Responsabil pentru operarea evenimentelor globale de solicitare ajax (de exemplu, ajaxStart sau ajaxStop). Dacă setați acest parametru la false , evenimentele globale pentru cererea dată nu va fi chemat.
  16. antete
    Tip: obiect.
    Acest parametru a fost introdus în jQuery-1.5 Aici puteți specifica anteturi de solicitare suplimentare (antet). Valorile acestei setări vor fi introduse înainte de apelul la funcția beforeSend, în care se pot face modificări finale ale antetelor.
  17. ifModified
    Tip: valoare booleană.
    Când această setare este setată la true , cererea va fi executată cu starea „reușită” numai dacă răspunsul de la server diferă de răspunsul anterior. jQuery verifică acest fapt uitându-se la antetul Last-Modified. Deoarece jQuery-1.4, pe lângă Last-Modified, se bifează și „etag” (ambele sunt furnizate de server și sunt necesare pentru a notifica browser-ul că datele solicitate de la server nu s-au schimbat de la solicitarea anterioară).
  18. esteLocal
    Tip: valoare booleană.
    Nou în jQuery-1.5.1 Vă permite să setați starea sursei paginii să fie locală (ca și cum ar fi prin protocolul fișierului), chiar dacă jQuery a recunoscut-o diferit. Biblioteca decide că pagina rulează local în cazul următoarelor protocoale: fișier, *-extensie și widget .Se recomandă setarea globală a valorii parametrului isLocal - folosind funcția $.ajaxSetup(), și nu în setările solicitărilor individuale ajax.
  19. jsonp
    Tip: șir sau boolean.
    Specifică numele parametrului care este adăugat la adresa URL a solicitării JSONP (în mod implicit, se utilizează „callback”). De exemplu, setarea (jsonp:"onJSONPLoad") este convertită în partea URL a șirului "onJSONPLoad=?" . Începând cu versiunea 1.5, setarea acestui parametru la false împiedică adăugarea lui la adresa URL parametru suplimentar. În acest caz, trebuie să setați valoarea setării jsonpCallback. De exemplu: (jsonp:false, jsonpCallback:"callbackName") .
  20. jsonpCallback
    Tip: șir sau funcție.
    Specifică numele funcției care va fi apelată atunci când serverul răspunde la o solicitare jsonp. În mod implicit, jQuery generează un nume arbitrar pentru această funcție, care este opțiunea preferată pentru a simplifica munca bibliotecii. Unul dintre motivele pentru care merită subliniat propria functie procesarea unei cereri jsonp este de a îmbunătăți stocarea în cache a cererilor GET.
    Începând cu jQuery-1.5, puteți specifica o funcție în acest parametru pentru a procesa singur răspunsul serverului. În acest caz, funcția specificată trebuie să returneze datele primite de la server (în funcția specificată, acestea vor fi disponibile în primul parametru).
  21. metoda (implicit: „GET”)
    Tip: sfoară.
    Parametru introdus în jQuery-1.9.0 Vă permite să specificați tipul de solicitare către server ("POST", "GET", "PUT")
  22. mimeType
    Tip: sfoară.
    Parametru introdus în jQuery-1.5.1 Acest câmp vă permite să specificați tipul de date în care este așteptat un răspuns de la server în loc de XHR
  23. parola
    Tip: sfoară.
    Parola de autentificare la server, dacă este necesar.
  24. procesarea datelor(implicit adevărat)
    Tip: valoare booleană.
    În mod implicit, datele trimise către server sunt convertite dintr-un obiect într-un șir de interogare (format URL: fName1=value1&fName2=value2&...) și trimise ca „application/x-www-form-urlencoded” . Dacă trebuie să trimiteți un document DOM sau alte date care nu pot fi convertite, setați opțiunea processData la false .
  25. scriptCharset
    Tip: sfoară.
    Se aplică numai solicitărilor Ajax GET, dataType poate fi fie „jsonp”, fie „script”. Dacă un server de pe un domeniu terță parte utilizează o altă codificare decât a dvs., trebuie să specificați codificarea serverului terță parte.
  26. statusCode
    Tip: obiect.
    Parametrul a fost introdus în jQuery-1.5.0 Un set de perechi care potrivesc codurile de execuție a cererii cu funcțiile care vor fi apelate. De exemplu, pentru codul 404 (paginile nu există), puteți afișa un mesaj pe ecran:

    $.ajax(( statusCode: ( 404: function() ( alert("pagina nu a fost gasita"); ) ) ));

    $ . ajax((

    statusCode :(

    404 : funcția () (

    alert("pagina nu a fost găsită");

    } ) ;


    Dacă cererea a avut succes, atunci ca parametru, functie anonima va lua aceiași parametri ca și funcțiile de gestionare a cererilor de succes (specificate în parametrul de succes), iar în caz de eroare la fel ca și funcțiile de eroare.
  27. succes(date, textStatus, jqXHR)
    Tip: funcție, matrice.
    Funcția care va fi apelată dacă cererea către server este finalizată cu succes. Ia 3 argumente:
    • date (date) trimise de server și preprocesate;
    • șir cu starea de execuție (textStatus);
    • obiect jqXHR (înainte de 1.5, XMLHttpRequest este folosit în loc de jqXHR). Începând cu jQuery 1.5, în loc de o singură funcție, acest parametru poate prelua o serie de funcții.
  28. pauză
    Tip: număr.
    Este timpul să așteptați un răspuns de la server în milisecunde. Rescrie setari globale același parametru în $.ajaxSetup(). Dacă acest timp este depășit, cererea va fi terminată cu o eroare și va fi declanșat un eveniment de eroare, care va avea starea „timeout”.
    Timpul este numărat din momentul în care a fost apelată funcția $.ajax. Se poate întâmpla ca mai multe alte solicitări să fie lansate în acest moment și browserul să amâne execuția cererii curente. În acest caz, timeout-ul se poate finaliza chiar dacă, de fapt, solicitarea nici măcar nu a început încă.
    În jQuery-1.4 și versiuni anterioare, când expiră timpul de expirare, obiectul XMLHttpRequest va intra într-o stare de eroare și accesarea câmpurilor sale poate provoca o excepție. În Firefox 3.0+, solicitările de script și JSONP nu vor fi anulate când expiră. Ele vor fi finalizate chiar și după expirarea acestui timp.
  29. tradiţional
    Tip: valoare booleană.
    Setați acest parametru la adevărat pentru a utiliza opțiunile tradiționale de conversie (serializare).
  30. tip(implicit: „GET”)
    Tip: sfoară.
    Similar cu parametrul metodei. Parametrul este utilizat în jQuery înainte de 1.9.0
  31. url(Mod implicit: adresa paginii curente)
    Tip: sfoară.
    Specifică adresa la care va fi trimisă cererea.
  32. nume de utilizator
    Tip: sfoară.
    Numele de utilizator de autentificat pe server, dacă este necesar.
  33. xhr(implicit: ActiveXObject în IE, XMLHttpRequest în alte browsere)
    Tip: functie.
    O funcție care va furniza un obiect XMLHttpRequest. În mod implicit, pentru browserele IE, acest obiect este un ActiveXObject, în caz contrar este un XMLHttpRequest. Cu această opțiune, puteți injecta propria versiune a acestui obiect.
  34. xhrFields
    Tip: obiect.
    Parametrul a apărut în jQuery-1.5.1 Set de perechi (nume: valoare) pentru modificarea/adăugarea valorilor câmpurilor corespunzătoare ale obiectului XMLHttpRequest. De exemplu, puteți seta proprietatea withCredentials la true atunci când faceți o solicitare pe mai multe domenii:

    $.ajax(( url: a_cross_domain_url, xhrFields: ( cuCredentials: true ) ));

    $ . ajax((

    url : a_cross_domain_url ,

    xhrFields :(

    cuCredentials: adevărat

    } ) ;

După cum am menționat mai sus, $.ajax() este metoda cea mai de bază, iar toate metodele ulterioare sunt doar pachetele sale. De foarte multe ori nu este nevoie să apelați această funcție. sunt mai multe alternative nivel inalt, cum ar fi , și . Sunt mai ușor de înțeles și de utilizat, deși $.ajax() este mai flexibil.

Cel mai simplu caz de utilizare ar fi apelarea $.ajax() fără parametri:

$ . ajax();

Managerii de evenimente

Setările beforeSend, error, dataFilter, succes și complete vă permit să setați handlere de evenimente care apar în anumite momente în execuția fiecărei solicitări ajax.

  • înainte de a trimite are loc chiar înainte ca cererea să fie trimisă către server;
  • eroare apare atunci când cererea eșuează;
  • dataFilter apare atunci când datele sosesc de la server. Vă permite să procesați datele „brute” trimise de server;
  • succes apare în cazul îndeplinirii cu succes a cererii;
  • complet apare în cazul oricărei finalizări a cererii.
  • succes: function()(

    alerta( „Date trimise cu succes.”) ;

    } ) ;

    Atenţie! Setările .success() , .error() și .complete() discutate mai sus au fost adăugate în jQuery-1.5 pe lângă metodele standard amânate .done() , .fail() și .then() pentru setarea handlerelor . . Cu toate acestea, începând cu jQuery-1.8, aceste trei metode vor fi depreciate.

    parametru dataType

    Funcția $.ajax() învață despre tipul de date trimise de server de la serverul însuși (folosind MIME). În plus, este posibil să indicați (clarăm) personal modul de interpretare a acestor date. Acest lucru se face folosind parametrul dataType. Valori posibile pentru acest parametru:

    • "xml"- documentul xml rezultat va fi disponibil sub formă de text. Poți lucra cu el mijloace standard jQuery (la fel ca și cu documentul html).
    • "html"- HTML-ul rezultat va fi disponibil sub formă de text. Dacă conține scripturi în etichete
      Cantitatea de ceva pe serverul site2.ru -

      PHP

      Acum trebuie să creăm un obiect JSON cu date în PHP. Să presupunem că avem un anumit contor stocat pe serverul site2.ru, îl vom solicita de pe site-ul site1.ru și vom obține doar un număr (cantitatea de ceva). Rețineți că trebuie să creăm un obiect JSONP în loc de un obiect JSON normal.

      // Cream o matrice cu datele pe care vrem sa le trimitem json ca raspuns $data = array("counter" => 5,); //Traduceți matricea în JSON $json_data=json_encode($data); // Setați codificarea și antetul tipului de conținut ("Content-type: application/json; charset=utf-8"); //JSONP - face ca un obiect JSONP să ecou $_GET["callback"] . " (" . $json_data . ");";

      Salvați fișierul ca counter.php și încărcați-l pe serverul site2.ru

      JAVASCRIPT

      Acum trebuie să apelați $.ajax în jQuery așa cum este descris mai jos:

      $(document).ready(funcție () ( $.ajax(( tip: "GET", url: "http://site2.ru/counter.php?callback=?", dataType: "jsonp", succes: funcția (date)( $(".text .counter").html(data.counter); ) )); ));

      Dacă nu specificați o funcție de apel invers, ci pur și simplu scrieți callback = ? - atunci numele funcției jQuery este înlocuit automat, dar puteți specifica în mod explicit și numele funcției, de exemplu callback=parseFunction.

      Acum rulați fișierul HTML pe site1.ru. Ar trebui să primiți un răspuns de la server cu date json. Puteți utiliza acest ajax între browsere și pentru $.getJSON, $.ajax, $.post și $.get.

      P.S. În exemplu, nu uitați să înlocuiți site2.ru - cu numele serverului dvs. la distanță căruia îi faceți o solicitare.

      Dacă aveți întrebări sau completări, scrieți în comentariile de mai jos.