Ce este o cerere de obținere și postare? Cum se trimite o solicitare de postare dintr-un browser: metoda de postare. Efectuarea cererilor GET cu PHP

ÎN În ultima vreme Văd din ce în ce mai multe întrebări pe forumul principal PHPClub pe tema creării cererilor POST și GET, precum și întrebări pe tema: „Cum pot genera o solicitare POST folosind funcția de antet.” Cred că necesitatea de a puncta „i”-urile în utilizarea această tehnologie, deoarece programatorii începători pur și simplu nu înțeleg principiile munca web, ca atare. Deci, să începem călătoria noastră prin lumea protocolului HTTP.

1. Protocolul HTTP. Introducere

Aș dori să clarific un mic lucru imediat. Cuvântul teribil protocol nu este altceva decât un acord al multor oameni, doar la un moment bun oamenii au decis: „Să facem așa, și atunci totul va fi bine”. Nu este nimic de care să ne fie frică, totul este pur și simplu scandalos și acum vom dezvălui această rușine. Deci, ce este protocolul HTTP și pentru ce este folosit?

1.1 Client și server

Nu există miracole în lume, și mai ales în lumea programării și a internetului! Acceptă asta ca pe un adevăr de neclintit. Și, dacă programul nu funcționează sau nu funcționează așa cum se dorește, atunci, cel mai probabil, fie este scris incorect, fie conține erori. Deci, cum cere browserul serverului să-i trimită ceva? Da, foarte simplu! Trebuie doar să te relaxezi puțin și să începi să te bucuri de proces :-)

1.2. Se scrie prima noastră solicitare HTTP

Dacă crezi că totul este prea complicat, atunci te înșeli. Omul este conceput în așa fel încât pur și simplu nu este capabil să creeze ceva complex, altfel el însuși se va încurca în el :-) Deci, există un browser și există un server Web. Browserul este întotdeauna inițiatorul schimbului de date. Un server Web nu va trimite pur și simplu nimic nimănui, astfel încât să trimită ceva către browser - browserul trebuie să ceară asta. Cel mai simplu HTTP Solicitarea ar putea arăta, de exemplu, astfel:

GET http://www.php.net/ HTTP/1.0\r\n\r\n

  • GET (tradus din engleză înseamnă „obține”) - un tip de cerere; tipul de solicitare poate fi diferit, de exemplu POST, HEAD, PUT, DELETE (ne vom analiza mai jos pe unele dintre ele).
  • http://www.php.net/ - URI (adresa) de la care dorim sa primim macar cateva informatii (firesc, speram sa invatam pagina HTML).
  • HTTP/1.0 este tipul și versiunea protocolului pe care le vom folosi atunci când comunicăm cu serverul.
  • \r\n este sfârșitul liniei, care trebuie repetat de două ori; de ce va deveni clar puțin mai târziu.
Puteți efectua această solicitare foarte simplu. Rulați programul telnet.exe, introduceți www.php.net ca gazdă, specificați portul 80 și pur și simplu introduceți această solicitare apăsând Enter de două ori ca \r\n\r\n. Ca răspuns, veți primi cod HTML pagina principala site-ul www.php.net.

1.3 Structura cererii

Să vedem în ce constă o solicitare HTTP. Totul este destul de simplu. Să începem cu faptul că o solicitare HTTP este un text complet semnificativ. În ce constă în cazul general? Vom lua în considerare protocolul HTTP 1.0. Asa de:

Linia de solicitare [General-Header | Antet cerere | Entity-Header ]\r\n[ Entity-Body ]

  • Linia de solicitare- șir de interogare
  • Format: „Metodă Solicitare-URI HTTP-Versiune\r\n”

  • Metodă- Metoda prin care va fi procesată resursa Request-URI poate fi GET, POST, PUT, DELETE sau HEAD.
  • Solicitare-URI- rudă sau referință absolută la o pagină cu un set de parametri, de exemplu, /index.html sau http://www.myhost.ru/index.html sau /index.html?a=1&b=qq. În acest din urmă caz, serverului i se va trimite o solicitare cu un set de variabile a și b cu valorile corespunzătoare, iar semnul „&” - un ampersand - servește ca separator între parametri.
  • Versiune HTTP- versiunea protocolului HTTP, în cazul nostru „HTTP/1.0”.

Suntem extrem de interesați de metodele de procesare GET și POST. Folosind metoda GET, puteți pur și simplu să transmiteți parametri scriptului și metoda POST puteți emula trimiterea formularului.

Pentru metoda GET, Request-URI ar putea arăta astfel: „/index.html?param1=1¶m2=2”.

  • General-Ant- partea principală a titlului.
    Format:
    Poate avea doar doi parametri: Data sau Pragma. Data - data Greenwich în formatul „Ziua săptămânii, Zi luna Anul HH:MM:SS GMT”, de exemplu, „Mar, 15 noiembrie 1994 08:12:31 GMT” - data creării cererii. Pragma poate avea o singură valoare fără cache, care dezactivează stocarea în cache a paginii.
  • Antetul cererii- parte a antetului care descrie cererea.

    Request-Header poate avea următorii parametri: Allow, Authorization, From, If-Modified-Since, Referer, User-Agent.
    În acest capitol, nu vom lua în considerare parametrul Autorizare, deoarece este folosit pentru a accesa resurse private, care nu este necesar foarte des. Puteți afla cum să creați singur un antet de acces autorizat la www.w3c.org.

  • Permite- stabilește metode de procesare acceptabile.
    Format: „Permite: GET | HEAD\n”.
    Parametrul este ignorat când se specifică metoda de procesare POST în Request-Line. Specifică metode acceptabile de procesare a cererilor. Serverele proxy nu modifică parametrul Allow și ajunge la server neschimbat.
  • Din - Adresa de e-mail care a trimis cererea.
    Format: „De la: adresă\r\n”.
    De exemplu, „De la: [email protected]\r\n”.
  • Dacă-Modificat-De vreme ce- indică faptul că cererea nu a fost modificată de la un moment dat.
    Format: „Dacă-Modificat-De la: data\r\n”
    Folosit numai pentru metoda de procesare GET. Data este specificată în GMT în același format ca și pentru parametrul Data din Antetul General.
  • Referitor- un link absolut către pagina de pe care a fost inițiată cererea, adică un link către pagina de pe care utilizatorul a venit la a noastră.
    Format: „Referitor: url\n”.
    Exemplu: „Referitor: www.host.ru/index.html\n”.
  • Agent utilizator- tipul browserului.
    De exemplu: „User-Agent: Mozilla/4.0\n”
  • Antet de entitate- parte a antetului care descrie datele Entitate-Corp.
    Această parte a cererii specifică parametrii care descriu corpul paginii. Entity-Header poate conține următorii parametri: Allow, Content-Coding, Content-Length, Content-Type, Expires, Last-Modified, extension-header.
  • Permite- un parametru similar cu Allow from General-Header.
  • Codificarea conținutului- codificarea datelor tip Entity-Body.
    Format: „Codificarea conținutului: x-gzip | x-compress | alt tip\n”.
    Exemplu: „Codificarea conținutului: x-gzip\n”. Caracterul „|”. înseamnă cuvântul „sau”, adică asta sau aia sau aia etc.
    Un alt tip poate indica modul în care datele sunt codificate, de exemplu, pentru metoda POST: „Content-Encoding: application/x-www-form-urlencoded\n”.
  • Conținut-Lungime- numărul de octeți trimiși către Entity-Body. Valoarea Content-Length are o semnificație complet diferită pentru datele trimise în format MIME, unde acționează ca un parametru pentru descrierea unei părți a datelor - „external/entity-body”. Numerele valide sunt numere întregi de la zero și mai sus.
    Exemplu: „Lungimea conținutului: 26457\n”.
  • Tipul de conținut- tipul datelor transmise.
    De exemplu: „Content-Type: text/html\n”.
  • Expiră- Ora la care pagina ar trebui să fie eliminată din memoria cache a browserului.
    Format: „Expiră: data\n”. Formatul de dată este același cu formatul de dată pentru parametrul Date din General-Header.
  • Modificat ultima dată- ora ultimei modificări a datelor transmise.
    Format: „Ultima modificare: dată\n”. Formatul de dată este același cu formatul de dată pentru parametrul Date din General-Header.
  • antetul extensiei- o parte a antetului, care poate fi destinată, de exemplu, să fie procesată de către un browser sau alt program care primește documentul. În această parte, puteți descrie parametrii dvs. în formatul „NumeParametru: valoare parametru\n”. Acești parametri vor fi ignorați dacă programul client nu știe cum să-i proceseze.
    De exemplu: „Cookie: r=1\r\n” - setează cookie-uri bine-cunoscute pentru pagină.

Și acum, după asemenea cuvinte groaznice, să încercăm să ne liniștim puțin și să înțelegem de ce avem nevoie? Desigur, vom înțelege cu exemple.

Să ne imaginăm că trebuie să obținem o pagină de pe site prin trecerea Cookie-urilor, altfel vom fi pur și simplu trimiși ca oaspeți neinvitați și, mai mult, se știe că aveți voie să accesați această pagină numai după ce ați vizitat pagina principală a site-ului. site-ul.

2 metoda GET

Să scriem cererea noastră.

GET http://www.site.ru/news.html HTTP/1.0\r\n
Gazdă: www.site.ru\r\n

Cookie: venit=1\r\n
\r\n

Aceasta cerere ne spune că dorim să obținem conținutul paginii de la http://www.site.ru/news.html folosind metoda GET. Câmpul Gazdă indică faptul că această pagină se află pe serverul www.site.ru, câmpul Referer indică că am venit pentru știri de pe pagina principală a site-ului, iar câmpul Cookie indică faptul că ni s-a atribuit un astfel de cookie. De ce sunt atât de importante câmpurile Gazdă, Referer și Cookie? Pentru că programatorii normali, atunci când creează site-uri dinamice, verifică câmpurile de date care apar în scripturi (inclusiv PHP) sub formă de variabile. Pentru ce e asta? Pentru a preveni, de exemplu, jefuirea site-ului, i.e. nu au setat un program pe el pentru descărcare automată, sau pentru ca o persoană care vizitează site-ul să ajungă întotdeauna la el doar din pagina principală etc.

Acum să ne imaginăm că trebuie să completăm câmpurile formularului din pagină și să trimitem o solicitare din formular, să fie două câmpuri în acest formular: autentificare și parolă (autentificare și parolă) - și, desigur, cunoaștem autentificarea si parola.

GET http://www.site.ru/news.html?login=Petya%20Vasechkin&password=qq HTTP/1.0\r\n
Gazdă: www.site.ru\r\n
Referer: http://www.site.ru/index.html\r\n
Cookie: venit=1\r\n
\r\n

Login-ul nostru este „Petya Vasechkin” De ce ar trebui să scriem Petya%20Vasechkin? Asta pentru ca Simboluri speciale pot fi recunoscute de server ca semne ale prezenței unui nou parametru sau sfârșitului unei cereri etc. Prin urmare, există un algoritm pentru codificarea numelor parametrilor și a valorilor acestora pentru a evita situațiile de eroare în cerere. Descriere completa a acestui algoritm poate fi găsit, iar PHP are funcții rawurlencode și rawurldecode pentru codificare și respectiv decodare. Aș dori să notez că PHP face decodarea în sine dacă parametrii codificați au fost trecuți în cerere. Acesta încheie primul capitol al cunoștințelor mele Protocolul HTTP. În capitolul următor ne vom uita la solicitări de construire precum POST (tradus din engleză ca „trimite”), care vor fi mult mai interesante, deoarece exact acest tip solicitările este utilizat la trimiterea datelor din formulare HTML.

3. Metoda POST.

Când Solicitare HTTP de tip POST, există două opțiuni pentru transferul câmpurilor din formularele HTML și anume, folosind algoritmul application/x-www-form-urlencoded și multipart/form-data. Diferențele dintre acești algoritmi sunt destul de semnificative. Cert este că primul tip de algoritm a fost creat cu mult timp în urmă, când limbaj HTML nu au oferit încă posibilitatea de a transfera fișiere prin formulare HTML. Deci, să ne uităm la acești algoritmi cu exemple.

3.1 Tip de conținut: application/x-www-form-urlencoded.

Scriem o solicitare similară cu solicitarea noastră GET de a transfera autentificarea și parola, despre care a fost discutată în capitolul anterior:


Gazdă: www.site.ru\r\n
Referer: http://www.site.ru/index.html\r\n
Cookie: venit=1\r\n
Tip de conținut: application/x-www-form-urlencoded\r\n
Lungimea conținutului: 35\r\n
\r\n

Aici vedem un exemplu de utilizare a câmpurilor de antet Content-Type și Content-Length. Lungimea conținutului indică câți octeți va ocupa zona de date, care este separată de antet printr-o altă întrerupere de linie \r\n. Dar parametrii care au fost plasați anterior în Request-URI pentru o solicitare GET sunt acum în Entity-Body. Se vede că sunt formate în același mod, trebuie doar să le scrieți după titlu. Vreau să subliniez încă un lucru punct important, nimic nu împiedică, concomitent cu setul de parametri din Entity-Body, plasarea parametrilor cu alte nume în Request-URI, de exemplu:

POST http://www.site.ru/news.html?type=user HTTP/1.0\r\n
.....
\r\n
login=Petya%20Vasechkin&parola=qq

3.2 Content-Type: multipart/form-data

De îndată ce lumea internetului și-a dat seama că ar fi bine să trimită fișiere prin formulare, consorțiul W3C a început să perfecționeze formatul de solicitare POST. Până atunci, formatul MIME (Multipurpose Internet Mail Extensions - extensii de protocol multifuncțional pentru crearea Mesaje de e-mail), prin urmare, pentru a nu reinventa roata, am decis să folosim o parte din acest format de generare a mesajelor pentru a crea cereri POST în protocolul HTTP.

Care sunt principalele diferențe dintre acest format și tipul application/x-www-form-urlencoded?

Principala diferență este că Entity-Body poate fi acum împărțit în secțiuni, care sunt separate prin granițe (limită). Cel mai interesant este că fiecare secțiune poate avea propriul antet pentru a descrie datele care sunt stocate în ea, de exemplu. Puteți transfera date într-o singură solicitare tipuri variate(cum in Scrisoare poștală Puteți transfera fișiere simultan cu text).

Asadar, haideti sa începem. Să luăm din nou același exemplu cu transferul de autentificare și parolă, dar acum într-un nou format.

POST http://www.site.ru/news.html HTTP/1.0\r\n
Gazdă: www.site.ru\r\n
Referer: http://www.site.ru/index.html\r\n
Cookie: venit=1\r\n

Lungimea conținutului: 209\r\n
\r\n
--1BEF0A57BE110FD467A \r\n
Conținut-Dispoziție: formular-date; nume="login" \r\n
\r\n
Petia Vasechkin \r\n
--1BEF0A57BE110FD467A \r\n
Conținut-Dispoziție: formular-date; nume="parolă" \r\n
\r\n
qq \r\n
--1BEF0A57BE110FD467A-- \r\n

Acum să înțelegem ce este scris. :-) Am evidențiat în mod special câteva caractere \r\n cu caractere aldine pentru a nu se îmbina cu datele. Dacă vă uitați cu atenție, veți observa câmpul de delimitare după Content-Type. Acest câmp specifică separatorul de secțiuni - chenar. Limita poate fi un șir format din litere latineși numere, precum și alte simboluri (din păcate, nu-mi amintesc care dintre ele). În corpul cererii, „--” se adaugă la începutul graniței, iar cererea se termină cu o graniță, la care se adaugă și caracterele „--” la sfârșit. Solicitarea noastră are două secțiuni, prima descrie câmpul de conectare, iar a doua descrie câmpul pentru parolă. Content-Disposition (tipul de date din secțiune) spune că acestea vor fi date din formular, iar câmpul de nume specifică numele câmpului. Aici se termină antetul secțiunii și ceea ce urmează este zona de date a secțiunii în care este plasată valoarea câmpului (nu este nevoie să codificați valoarea!).

Aș dori să vă atrag atenția asupra faptului că nu trebuie să utilizați Content-Length în anteturile de secțiune, dar în antetul cererii ar trebui, iar valoarea acesteia este dimensiunea întregului Entity-Body, care apare după al doilea \ r\n după lungimea conținutului: 209\ r\n. Acestea. Entity-Body este separat de antet printr-o întrerupere suplimentară de linie (care poate fi văzută și în secțiuni).

Acum să scriem o solicitare pentru a transfera un fișier.

POST http://www.site.ru/postnews.html HTTP/1.0\r\n
Gazdă: www.site.ru\r\n
Referer: http://www.site.ru/news.html\r\n
Cookie: venit=1\r\n
Tip de conținut: date multiple/form-date; limită=1BEF0A57BE110FD467A\r\n
Lungimea conținutului: 491\r\n
\r\n
--1BEF0A57BE110FD467A \r\n
Conținut-Dispoziție: formular-date; name="news_header" \r\n
\r\n
Stiri de exemplu \r\n
--1BEF0A57BE110FD467A \r\n
Conținut-Dispoziție: formular-date; name="file_news"; filename="news.txt" \r\n
Tip de conținut: aplicație/flux-octet \r\n
Conținut-Transfer-Codificare: binar \r\n
\r\n
Și iată știrile, care se află în fișierul news.txt \r\n
--1BEF0A57BE110FD467A-- \r\n

ÎN în acest exemplu prima secțiune trimite titlul știrii, iar a doua secțiune trimite fișierul news.txt. Dacă sunteți atent, veți vedea câmpurile pentru numele fișierului și tipul conținutului în a doua secțiune. Câmpul nume de fișier specifică numele fișierului trimis, iar câmpul Content-Type specifică tipul acestui fișier. Application/octet-stream indică faptul că acesta este un flux de date standard, iar Content-Transfer-Encoding: binary indică faptul că acestea sunt date binare, necodificate în niciun fel.

Un punct foarte important. Majoritatea scripturilor CGI sunt scrise oameni destepti, așa că le place să verifice tipul fișierului primit, care este în Content-Type. Pentru ce? Cel mai adesea, încărcarea fișierelor pe site-uri web este folosită pentru a primi imagini de la vizitator. Deci, browserul însuși încearcă să determine ce fel de fișier dorește să trimită vizitatorul și inserează tipul de conținut corespunzător în cerere. Scriptul îl verifică la primire și, de exemplu, dacă nu este un gif sau jpeg, îl ignoră acest fișier. Prin urmare, atunci când creați o solicitare „manual”, aveți grijă de valoarea Content-Type, astfel încât să fie cel mai apropiată de formatul fișierului transferat.

În exemplul nostru, este generată o cerere în care fisier text. O solicitare pentru transferul unui fișier binar este generată în același mod.

4. Post-scriptum.

Cred că nu merită să vorbim în detaliu despre trimiterea cererilor către server. Aceasta este o chestiune de tehnologie pur RHP :-). Citiți cu atenție secțiunea despre funcțiile pentru lucrul cu prize sau despre funcțiile modulului CURL în documentație oficială RNR.

Din cele de mai sus, sper că acum este clar de ce întrebarea este: „Cum pot genera o solicitare POST folosind funcția antet?” - fără sens. Funcția header(string) adaugă o intrare numai la antetul cererii, dar nu și la corpul solicitării.

Există un alt tip de solicitare - Content-Type: multipart/mixed, sper că după ce ați citit acest articol veți înțelege ușor acest tip. Îl poți studia în detaliu

Ceea ce au în comun este că funcționează la fel. Din punct de vedere tehnic, nu există nicio diferență între ele. Dar există diferențe ideologice.

Voi vorbi despre ele în contextul PHP. Vă rugăm să rețineți că protocolul HTTP este indirect legat de PHP, deoarece a fost creat pentru schimb pagini html iar PHP pur și simplu extinde capacitățile ambelor.

Solicitarea GET este folosită pentru a primi date și POST este folosit pentru a trimite. (Amintiți-vă că din punct de vedere tehnic funcționează la fel).

Prin urmare, în contextul PHP, pe baza acestei ideologii, am făcut următoarele:
1. De fiecare dată când porniți PHP, matricele superglobale ($_GET, $_POST) sunt create implicit.
2. Dacă există un semn de întrebare (?) în șirul de interogare. Totul după ce este luat în considerare parametrii Cererea GET, acestea sunt prezentate în formatul "key"="valoare" iar caracterul ampersand (&) este folosit ca delimitator.
Exemplu:
GET /index.php?name=Andrey&surname=Galkin
Acesta este un șir de interogare, există 2 parametri. acești parametri vor intra în tabloul $_GET.
3. $_POST este completat într-un mod diferit. conținutul acestei matrice este completat din „anteturile cererii”. Adică dintr-un loc clar ascuns vederii. Browserul se ocupă de toate treburile creării unor astfel de anteturi. Deși uneori ceva este editat în titluri manual.

Cel mai adesea, o cerere de postare este utilizată în formulare (pentru a trimite date).

De exemplu, avem un formular de autentificare cu 2 câmpuri: autentificare și parolă.

Să ne imaginăm că folosim metoda GET. Apoi, la trimiterea formularului, vom merge la următoarea adresă /login.php?login=Andrey&password=123 Veți fi de acord că transmiterea unor astfel de informații în acest mod nu este deloc sigură. Oricine vă poate deschide browserul și, începând să introducă adresa site-ului, vă poate vedea parolele și login-urile din istoric.

Dar dacă am specifica metoda POST, am primi următoarea solicitare:
POST /login.php (login=Andrey&password=123) ceea ce este între paranteze ar fi ascuns și nu ar fi salvat în niciun fel în browser.

Pentru a rezuma:
GET este a obține pagina specifică V o anumită formă(triere, pagina curenta blog, bară de căutare etc.).
POST - pentru trimiterea de date care nu afectează afișarea paginii, în sensul că aceste date afectează doar rezultatul scriptului (autentificări, parole, numere de card de credit, mesaje etc.).

Si inca una Vești bune pot fi combinate, de exemplu
POST /index.php?page=login (login=Andrey&password=123) Cred că am explicat deja suficient ce va veni din asta și ce parametri vor intra în ce matrice.

Astăzi am vrut să intru puțin în lucrurile primitive și să descriu ce se poate găsi în retea mondialaîn cantităţi mari şi fără prea mult efort. Vom vorbi practic despre sfântul sfintelor protocolului HTTP: cererile POST și GET.

Mulți se vor întreba de ce? Voi răspunde pe scurt și clar: nu toată lumea știe ce este și de ce este nevoie, iar cei care vor să învețe despre ea (în timp ce înțeleg puțin în domeniul IT) de multe ori nu pot înțelege ce este scris în multe, multe articole consacrate acestui lucru subiect. Voi încerca să explic cu degetele mele ce sunt solicitările POST și GET și pentru ce sunt folosite.
Deci, să începem călătoria noastră într-un basm...
Daca citesti acest mesaj, atunci măcar știi cum arată Internetul și ce este un site de Internet. Omitând toate subtilitățile muncii world wide web, vom opera cu concepte precum utilizator și site. Orice s-ar spune, aceste două entități trebuie cumva să interacționeze între ele. De exemplu, oamenii comunică între ei prin gesturi, emoții și vorbire, animalele scot niște sunete, dar ce se întâmplă atunci când o persoană și o resursă de internet „comună”? Aici avem un caz de schimb de informații, care poate fi transferat într-o conversație umană „Întrebare-Răspuns”. Mai mult, atât utilizatorul, cât și site-ul pot pune întrebări și răspunsuri. Când vorbim despre un site web, întrebările și răspunsurile sale, de regulă, sunt întotdeauna exprimate sub forma unei pagini de internet cu un text sau altul. Când despre care vorbim despre utilizator, atunci totul se întâmplă datorită solicitărilor GET și POST (desigur nu numai, dar vorbim despre ele).

Astfel, am aflat că obiectele noastre tematice sunt necesare pentru a „comunica” cu site-urile. Mai mult, atât solicitările GET, cât și POST pot fi folosite pentru a „pune întrebări” site-ului și pentru a „răspunde” la ele. In ce fel sunt ei diferiti? Totul este destul de simplu. Totuși, pentru a explica diferențele, va trebui să luăm în considerare un exemplu, pentru care vom lua site-ul unui plan de magazin online.
Probabil ai observat adesea când căutai ceva în interior magazine online, că atunci când a apelat la o căutare folosind filtre, adresa site-ului a trecut de la frumosul „http://magaazin.ru” la teribilul „http://magaazin.ru/?category=shoes&size=38”. Deci, tot ce urmează după simbolul „?” este solicitarea dvs. GET către site și, pentru a fi complet precis, în în acest caz, Se pare că întrebați site-ul ce are în categoria „Pantofi” din mărimile „38” (exemplul ăsta este luat din capul meu, în realitate totul poate să nu arate atât de evident). Ca urmare, avem că putem pune întrebări noi înșine, indicându-le în bara de adrese a site-ului. Este evident că aceasta metoda are mai multe dezavantaje. În primul rând, oricine se află lângă utilizator la computer poate spiona cu ușurință toate datele, așa că folosește acest tip Solicitările de transfer de parole sunt foarte descurajate. În al doilea rând, există o limită a lungimii șirului care poate fi transferat din câmpul de adresă a site-ului, ceea ce înseamnă că nu va fi posibil să transferați multe date. in orice caz un plus cert Utilizarea solicitărilor GET este ușurința sa de utilizare și capacitatea de a interoga rapid site-ul, ceea ce este util în special în timpul dezvoltării, dar asta este o altă poveste...
Acum să vorbim despre solicitările POST. Este posibil ca cititorii inteligenți să fi realizat că principala diferență între această solicitare și omologul său este secretul datelor transmise. Dacă luăm în considerare un magazin online, un exemplu izbitor în care se folosește o solicitare POST este înregistrarea pe site. Site-ul vă solicită datele, completați aceste date și când faceți clic pe butonul „Înregistrare” trimiteți răspunsul dumneavoastră. Mai mult, aceste date nu vor fi afișate în niciun fel extern. De asemenea, este de remarcat faptul că pot solicita destul de un numar mare de informaţii – şi semnificative Restricții POST cererea nu are. Ei bine, dacă atingeți minusul, atunci o astfel de solicitare nu poate fi generată rapid. Nu poți face asta fără abilități speciale. Deși în realitate totul nu este atât de complicat, dar din nou, asta este o altă poveste.
Să rezumam. Solicitările POST și GET sunt necesare pentru „comunicarea” între utilizator și site. Ele sunt în esență aproape opuse unul față de celălalt. Utilizarea anumitor tipuri de interogări depinde de situația specifică și utilizarea unui singur tip de interogare este extrem de incomod.

1. Protocolul HTTP. Introducere

Aș dori să clarific un mic lucru imediat. Cuvântul teribil protocol nu este altceva decât un acord al multor oameni, doar la un moment bun oamenii au decis: „Să facem așa, și atunci totul va fi bine”. Nu este nimic de care să ne fie frică, totul este pur și simplu revoltător și acum vom dezvălui această rușine. Deci, ce este protocolul HTTP și pentru ce este folosit?

1.1 Client și server

Nu există miracole în lume, și mai ales în lumea programării și a internetului! Acceptă asta ca pe un adevăr de neclintit. Și, dacă programul nu funcționează sau nu funcționează așa cum se dorește, atunci, cel mai probabil, fie este scris incorect, fie conține erori. Deci, cum cere browserul serverului să-i trimită ceva? Da, foarte simplu! Trebuie doar să te relaxezi puțin și să începi să te bucuri de proces :-)

1.2. Se scrie prima noastră solicitare HTTP

Dacă crezi că totul este prea complicat, atunci te înșeli. Omul este conceput în așa fel încât pur și simplu nu este capabil să creeze ceva complex, altfel el însuși se va încurca în el :-) Deci, există un browser și există un server Web. Browserul este întotdeauna inițiatorul schimbului de date. Un server Web nu va trimite pur și simplu nimic nimănui, astfel încât să trimită ceva către browser - browserul trebuie să ceară asta. Cea mai simplă solicitare HTTP ar putea arăta astfel:


GET http : //www.php.net/ HTTP/1.0rnrn


* GET (tradus din engleză înseamnă „obține”) - tipul de solicitare, tipul de solicitare poate fi diferit, de exemplu POST, HEAD, PUT, DELETE (ne vom analiza mai jos pe unele dintre ele).
* http://www.php.net/ - URI (adresa) de la care dorim sa primim macar cateva informatii (firesc, speram sa invatam pagina HTML).
* HTTP/1.0 - tipul și versiunea protocolului pe care îl vom folosi atunci când comunicăm cu serverul.
* rn - sfârșitul liniei, care trebuie repetat de două ori; de ce va deveni clar puțin mai târziu.

Puteți efectua această solicitare foarte simplu. Rulați programul telnet.exe, introduceți www.php.net ca gazdă, specificați portul 80 și pur și simplu introduceți această solicitare apăsând Enter de două ori ca rnrn. Ca răspuns, veți primi codul HTML al paginii principale a site-ului www.php.net.

1.3 Structura cererii

Să vedem în ce constă o solicitare HTTP. Totul este destul de simplu. Să începem cu faptul că o solicitare HTTP este un text complet semnificativ. În ce constă? caz general? Vom lua în considerare protocolul HTTP 1.0. Asa de :


Solicitare - Linie [ General - Antet | Solicitare - Antet | Entitate - Antet ] rn [ Entitate - Corp ]


* Request-Line - linie de solicitare
*

Format : "Metodă Solicitare-URI HTTP-Versionrn"
* Metoda -
metoda prin care va fi procesată resursa Request-URI poate fi GET, POST, PUT, DELETE sau HEAD.
* Request-URI - un link relativ sau absolut către o pagină cu un set de parametri, de exemplu, /index.html sau http://www.myhost.ru/index.html sau /index.html?a=1&b= q. În acest din urmă caz, serverului i se va trimite o solicitare cu un set de variabile a și b cu valorile corespunzătoare, iar semnul „&” - un ampersand - servește ca separator între parametri.
* HTTP-Version - versiunea protocolului HTTP, în cazul nostru „HTTP/1.0”.

Suntem extrem de interesați de metodele de procesare GET și POST. Cu metoda GET puteți trece pur și simplu parametri scriptului, iar cu metoda POST puteți emula trimiterea formularelor.

Pentru metoda GET, Request-URI ar putea arăta astfel: „/index.html?param1=1¶m2=2”.

* General-Header - partea principală a antetului.
Format:
Poate avea doar doi parametri: Data sau Pragma. Data - data Greenwich în formatul „Ziua săptămânii, Zi luna Anul HH:MM:SS GMT”, de exemplu, „Mar, 15 noiembrie 1994 08:12:31 GMT” - data creării cererii. Pragma poate avea o singură valoare fără cache, care dezactivează stocarea în cache a paginii.

* Request-Header - parte a antetului care descrie cererea.

Request-Header poate avea următorii parametri : Permite, Autorizare, De la, Dacă-Modificat-De când, Referer, User-Agent.
În acest capitol, nu vom acoperi parametrul Autorizare, deoarece este folosit pentru a accesa resurse închise, ceea ce nu este necesar foarte des. Puteți afla cum să creați singur un antet de acces autorizat la www.w3c.org.

* Permite - setează metode de procesare acceptabile.
Format: „Permite: GET | HEADn”.
Parametrul este ignorat când se specifică metoda de procesare POST în Request-Line. Specifică metode acceptabile de procesare a cererilor. Serverele proxy nu modifică parametrul Allow și ajunge la server neschimbat.

* De la - adresa de e-mail a persoanei care a trimis cererea.
Format: „De la: aderssrn”.
De exemplu, „De la: [email protected]".

* If-Modified-Since - indică faptul că cererea nu a fost modificată de la un moment dat.
Format: „Dacă-Modificat-Din: datern”
Folosit numai pentru metoda de procesare GET. Data este specificată în GMT în același format ca și pentru parametrul Data din Antetul General.

* Referrer - un link absolut către pagina de pe care a fost inițiată solicitarea, adică un link către pagina de pe care utilizatorul a venit la a noastră.
Format: „Referitor: urln”.
Exemplu: „Referitor: www.host.ru/index.htmln”.
* User-Agent - tip browser.
De exemplu: „User-Agent: Mozilla/4.0n”

* Entity-Header - parte a antetului care descrie datele Entity-Body.
Această parte a cererii specifică parametrii care descriu corpul paginii. Entity-Header poate conține următorii parametri: Allow, Content-Encoding, Content-Length, Content-Type, Expires, Last-Modified, extensie-header.

* Allow - un parametru similar cu Allow from General-Header.

* Codificarea conținutului - Tipul de codificare a datelor Entity-Body.
Format: „Codificarea conținutului: x-gzip | x-compress | alt tip”.
Exemplu: „Codificarea conținutului: x-gzipn”. Caracterul „|”. înseamnă cuvântul „sau”, adică asta sau aia sau aia etc.
Un alt tip poate indica modul în care datele sunt codificate, de exemplu, pentru metoda POST: „Content-Encoding: application/x-www-form-urlencodedn”.

* Content-Length - numărul de octeți trimiși către Entity-Body. Valoarea Content-Length are o semnificație complet diferită pentru datele trimise în format MIME, unde acționează ca un parametru pentru descrierea unei părți a datelor - „external/entity-body”. Numerele valide sunt numere întregi de la zero și mai sus.
Exemplu: „Lungimea conținutului: 26457n”.

* Content-Type - tipul datelor transmise.
De exemplu: „Content-Type: text/htmln”.

* Expiră - Ora la care pagina ar trebui să fie ștearsă din memoria cache a browserului.
Format: „Expiră: datat”. Formatul de dată este același cu formatul de dată pentru parametrul Date din General-Header.

* Ultima modificare - ora ultima schimbare date trimise.
Format: „Ultima modificare: datată”. Formatul de dată este același cu formatul de dată pentru parametrul Date din General-Header.

* Extention-header - parte a antetului, care poate fi destinată, de exemplu, să fie procesată de un browser sau alt program care primește documentul. În această parte, puteți descrie parametrii dvs. în formatul „ParameterName: parametervaluen”. Acești parametri vor fi ignorați dacă programul client nu știe cum să-i proceseze.
De exemplu: „Cookie: r=1rn” – setează cookie-uri binecunoscute pentru pagină.

Și acum, după asemenea cuvinte groaznice, să încercăm să ne liniștim puțin și să înțelegem de ce avem nevoie? Desigur, vom înțelege cu exemple.

Să ne imaginăm că trebuie să obținem o pagină de pe site prin trecerea Cookie-urilor, altfel vom fi pur și simplu trimiși ca oaspeți neinvitați și, mai mult, se știe că aveți voie să accesați această pagină numai după ce ați vizitat pagina principală a site-ului. site-ul.

2 metoda GET

Să scriem cererea noastră.


OBȚINE http:
Gazdă: www. site-ul. fugi

Cookie: venit = 1rn
rn


Această solicitare ne spune că dorim să obținem conținutul paginii de la http://www.site.ru/news.html folosind metoda GET. Câmpul Gazdă indică acest lucru această pagină se află pe serverul www.site.ru, câmpul Referer indică faptul că am venit pentru știri de pe pagina principală a site-ului, iar câmpul Cookie indică că ni s-a atribuit un astfel de cookie. De ce sunt atât de importante câmpurile Gazdă, Referer și Cookie? Pentru că programatorii normali, atunci când creează site-uri dinamice, verifică câmpurile de date care apar în scripturi (inclusiv PHP) sub formă de variabile. Pentru ce e asta? Pentru a preveni, de exemplu, jefuirea site-ului, i.e. nu au setat un program pe el pentru descărcare automată, sau pentru ca o persoană care vizitează site-ul să ajungă întotdeauna la el doar din pagina principală etc.

Acum să ne imaginăm că trebuie să completăm câmpurile formularului din pagină și să trimitem o solicitare din formular, să fie două câmpuri în acest formular: autentificare și parolă (autentificare și parolă) - și, desigur, cunoaștem autentificarea si parola.


OBȚINE http: //www.site.ru/news.html?login=Petya%20Vasechkin&password=qq HTTP/1.0rn
Gazdă: www. site-ul. fugi
Referer: http://www.site.ru/index.htmlrn
Cookie: venit = 1rn
rn


Login-ul nostru este „Petya Vasechkin” De ce ar trebui să scriem Petya%20Vasechkin? Acest lucru se datorează faptului că caracterele speciale pot fi recunoscute de către server ca semne ale prezenței unui nou parametru sau ale sfârșitului unei cereri etc. Prin urmare, există un algoritm pentru codificarea numelor parametrilor și a valorilor acestora pentru a evita situațiile de eroare în cerere. O descriere completă a acestui algoritm poate fi găsită aici, iar PHP are funcții rawurlencode și rawurldecode pentru codificare și respectiv decodare. Aș dori să notez că PHP face decodarea în sine dacă parametrii codificați au fost trecuți în cerere. Aceasta încheie primul capitol al cunoașterii mele cu protocolul HTTP. În capitolul următor ne vom uita la solicitări de construire precum POST (tradus din engleză ca „trimite”), care vor fi mult mai interesante, deoarece Acesta este tipul de solicitare care este folosit la trimiterea datelor din formulare HTML.

3. Metoda POST.

În cazul unei solicitări HTTP POST, există două opțiuni pentru transferul câmpurilor din formularele HTML și anume, folosind algoritmul application/x-www-form-urlencoded și multipart/form-data. Diferențele dintre acești algoritmi sunt destul de semnificative. Cert este că primul tip de algoritm a fost creat cu mult timp în urmă, când limbajul HTML nu prevedea încă posibilitatea de a transfera fișiere prin Formulare HTML. Deci, să ne uităm la acești algoritmi cu exemple.

3.1 Tip de conținut: application/x-www-form-urlencoded.

Scriem o solicitare similară cu solicitarea noastră GET de a transfera autentificarea și parola, despre care a fost discutată în capitolul anterior:


POSTĂ http: //www.site.ru/news.html HTTP/1.0rn
Gazdă: www. site-ul. fugi
Referer: http://www.site.ru/index.htmlrn
Cookie: venit = 1rn
Conținut - Tip: cerere / x - www - formular - urlencodedrn
Continut - Lungime: 35rn
rn


Aici vedem un exemplu de utilizare a câmpurilor de antet Content-Type și Content-Length. Content-Length indică câți octeți va ocupa zona de date, care este separată de antet printr-un alt line feed rn. Dar parametrii care au fost plasați anterior în Request-URI pentru o solicitare GET sunt acum în Entity-Body. Se vede că sunt formate exact în același mod, trebuie doar să le scrieți după titlu. Aș dori să mai notez un punct important: nimic nu împiedică, simultan cu setul de parametri din Entity-Body, plasarea parametrilor cu alte nume în Request-URI, de exemplu:


POSTĂ http: //www.site.ru/news.html?type=user HTTP/1.0rn
.....
rn
autentificare = Petya % 20Vasechkin & parola = qq


3.2 Content-Type: multipart/form-data

De îndată ce lumea internetului și-a dat seama că ar fi bine să trimită fișiere prin formulare, consorțiul W3C a început să perfecționeze formatul de solicitare POST. Până atunci, formatul MIME (Multipurpose Internet Mail Extensions - extensii de protocol multifuncțional pentru generarea de mesaje Mail) era deja utilizat pe scară largă, așa că pentru a nu reinventa roata, am decis să folosim o parte a acestui format generarea de mesaje pentru a crea cereri POST în protocolul HTTP.

Care sunt principalele diferențe dintre acest format și tipul application/x-www-form-urlencoded?

Principala diferență este că Entity-Body poate fi acum împărțit în secțiuni, care sunt separate prin granițe (limită). Cel mai interesant este că fiecare secțiune poate avea propriul antet pentru a descrie datele care sunt stocate în ea, de exemplu. într-o singură solicitare puteți transfera date de diferite tipuri (ca într-o scrisoare Mail, puteți transfera fișiere în același timp cu text).

Asadar, haideti sa începem. Să luăm din nou același exemplu cu transferul de autentificare și parolă, dar acum într-un nou format.


POSTĂ http: //www.site.ru/news.html HTTP/1.0rn
Gazdă: www. site-ul. fugi
Referer: http://www.site.ru/index.htmlrn
Cookie: venit = 1rn

Conținut - Lungime: 209rn
rn
-- 1BEF0A57BE110FD467Arn
Conţinut - Dispoziţie : formă - date ; nume = "login" rn
rn
Petya Vasechkinrn
-- 1BEF0A57BE110FD467Arn
Conţinut - Dispoziţie : formă - date ; nume = „parolă” rn
rn
qqrn
-- 1BEF0A57BE110FD467A -- rn


Acum să înțelegem ce este scris. :-) Am evidențiat în mod deliberat câteva caractere rn cu caractere aldine pentru a nu se îmbina cu datele. Dacă vă uitați cu atenție, veți observa câmpul de delimitare după Content-Type. Acest câmp specifică separatorul de secțiuni - chenar. Un șir format din litere și numere latine, precum și alte simboluri (din păcate, nu-mi amintesc care altele) poate fi folosit ca chenar. În corpul cererii, „--” se adaugă la începutul graniței, iar cererea se termină cu o graniță, la care se adaugă și caracterele „--” la sfârșit. Solicitarea noastră are două secțiuni, prima descrie câmpul de conectare, iar a doua descrie câmpul pentru parolă. Content-Disposition (tipul de date din secțiune) spune că acestea vor fi date din formular, iar câmpul de nume specifică numele câmpului. Aici se termină antetul secțiunii și ceea ce urmează este zona de date a secțiunii în care este plasată valoarea câmpului (nu este nevoie să codificați valoarea!).

Aș dori să vă atrag atenția asupra faptului că nu trebuie să utilizați Content-Length în anteturile de secțiune, dar în antetul cererii ar trebui și valoarea acesteia este dimensiunea întregului Entity-Body, care apare după al doilea rn următorul conținut-lungime: 209rn. Acestea. Entity-Body este separat de antet printr-o întrerupere suplimentară de linie (care poate fi văzută și în secțiuni).

Acum să scriem o solicitare pentru a transfera un fișier.


POSTĂ http: //www.site.ru/postnews.html HTTP/1.0rn
Gazdă: www. site-ul. fugi
Referer: http://www.site.ru/news.htmlrn
Cookie: venit = 1rn
Tip de conținut: date multiple/form-date; limita = 1BEF0A57BE110FD467Arn
Conținut - Lungime: 491rn
rn
-- 1BEF0A57BE110FD467Arn
Conţinut - Dispoziţie : formă - date ; nume = "news_header" rn
rn
Stiri de exemplu
-- 1BEF0A57BE110FD467Arn
Conţinut - Dispoziţie : formă - date ; nume = "fișier_știri" ; filename = "news.txt" rn
Conținut - Tip: aplicație / octet - streamrn
Conținut - Transfer - Codificare : binaryrn
rn
Iată știrile, care se află în dosarul de știri. txtrn
-- 1BEF0A57BE110FD467A -- rn


În acest exemplu, prima secțiune trimite titlul știrilor, iar a doua secțiune trimite fișierul news.txt. Dacă sunteți atent, veți vedea câmpurile pentru numele fișierului și tipul conținutului în a doua secțiune. Câmpul nume de fișier specifică numele fișierului trimis, iar câmpul Content-Type specifică tipul acestui fișier. Application/octet-stream indică faptul că acesta este un flux de date standard, iar Content-Transfer-Encoding: binary indică faptul că acestea sunt date binare, necodificate în niciun fel.

Un punct foarte important. Majoritate Scripturi CGI scris de oameni inteligenți, așa că le place să verifice tipul fișierului primit, care este în Content-Type. Pentru ce? Cel mai adesea, încărcarea fișierelor pe site-uri web este folosită pentru a primi imagini de la vizitator. Deci, browserul însuși încearcă să determine ce fel de fișier dorește să trimită vizitatorul și inserează tipul de conținut corespunzător în cerere. Scriptul îl verifică la primire și, de exemplu, dacă nu este un gif sau jpeg, ignoră acest fișier. Prin urmare, atunci când creați o solicitare „manual”, aveți grijă de valoarea Content-Type, astfel încât să fie cel mai apropiată de formatul fișierului transferat.

Imagine/gif pentru gif
imagine/jpeg pentru jpeg
imagine/png pentru png
imagine/tiff pentru tiff (care este folosit extrem de rar, formatul este prea încăpător)

În exemplul nostru, este generată o cerere în care este transferat un fișier text. O solicitare pentru transferul unui fișier binar este generată în același mod.

4. Post-scriptum.

Cred că nu merită să vorbim în detaliu despre trimiterea cererilor către server. Aceasta este o chestiune de tehnologie pur RHP :-). Este suficient să citiți cu atenție secțiunea despre funcțiile pentru lucrul cu socket-uri sau despre funcțiile modulului CURL din documentația oficială PHP.

Din cele de mai sus, sper că acum este clar de ce întrebarea este: „Cum pot genera o solicitare POST folosind funcția antet?” - fără sens. Funcția header(string) adaugă o intrare numai la antetul cererii, dar nu și la corpul solicitării.

Înapoi

În zilele noastre, doar două sunt cele mai des folosite Metoda HTTP: GET și POST. Dar s-a dovedit că și printre acești doi „pini” dezvoltatorii web reușesc să se piardă. Există o explicație pentru aceasta: ambele metode pot fi folosite pentru a obține același rezultat. Dar trebuie să ne amintim că utilizarea necugetă a oricăreia dintre metode poate duce la consecințe dezastruoase, inclusiv sarcini grele la canal și găuri de securitate.

Pentru a evita acest lucru, este suficient să înțelegeți pur și simplu mai detaliat scopurile și diferențele acestor metode.

Dacă vă aprofundați în sensul numelor de metode, multe vor deveni mai clare. GET (din engleză pentru a primi), i.e. ar trebui folosit pentru a interoga datele. POST (din engleză send by mail) - folosit pentru a trimite date către server. Totul pare a fi extrem de simplu și clar. Dar cine vrea să dezvolte site-uri web puțin mai complicate decât un site de cărți de vizită cu un singur formular? părere, este mai bine să cunoașteți mai bine întrebarea.

Solicitări HTTP sigure și nesigure

Specificația HTTP 1.1 introduce două concepte: cerere securizată și nesigură sau, mai precis, metoda.

Metodele sigure sunt metode care pot solicita doar informații. Ele nu pot modifica resursa solicitată și nici nu pot duce la rezultate nedorite pentru utilizator, alții sau server. Exemple de cele sigure sunt Solicitare HTML codul paginii web sau imaginea. Metodele sigure includ HEAD și GET.

Nota

În realitate, meșterii, desigur, pot provoca prejudicii cu cererile GET. De exemplu, bucle de interogare.

Interogările nesigure, după cum toată lumea a ghicit deja, pot duce la consecințe negative dacă sunt folosite din nou. Astfel de solicitări pot modifica conținutul resursei care este accesată. Exemple de astfel de solicitări: trimiterea de mesaje, înregistrarea, plăți online. Metodele nesigure includ POST, PUT, DELETE.

Metode idempotente

Idempotenta este o proprietate a metodelor care, cu numeroase apeluri repetate, va returna acelasi rezultat, cu exceptia cazurilor in care informatia este invechita. Aceasta înseamnă că atunci când accesează aceeași adresă URL, toți utilizatorii vor vedea aceeași pagină web, imagine, videoclip etc. Metodele GET, PUT, DELETE au această proprietate.

Și acum mai multe despre noi înșine metode GETși POST: vom scrie un scurt „cv” pentru toată lumea.

OBȚINE

  • conceput pentru a primi date de la server;
  • corpul cererii este gol;
  • procesate pe partea serverului mai rapid și cu un consum mai mic de resurse server datorită corpului de cerere gol;
  • Variabilele sunt transmise bara de adresa(așa vede utilizatorul, tehnic datele sunt furnizate în linia de interogare) și, prin urmare, informațiile despre variabile și valorile acestora sunt vizibile (datele nu sunt protejate);
  • capabil să transmită o cantitate mică de date către server: există restricții privind lungimea URL-ului, care depinde de browser, de exemplu, IE6 = 2Kb. Dezvoltatorii Yahoo! recomandă să vă concentrați pe acest număr;
  • poate transmite doar caractere ASCII;
  • o astfel de solicitare poate fi copiată și salvată (de exemplu, în marcaje);
  • cererea poate fi stocată în cache (aceasta poate fi controlată);
  • pentru a reduce și mai mult sarcina pe canal și pe server, sunt disponibile cereri condiționate și parțiale;
  • nu rupe conexiune HTTP(cu modul keepAlive activat pe server).

POST

  • destinat trimiterii de date către server;
  • transferul de date are loc în corpul cererii;
  • procesarea pe partea serverului este mai lentă și „mai grea” decât GET, deoarece pe lângă anteturi, trebuie analizat corpul cererii;
  • capabil să transmită cantități mari de date;
  • capabil să transfere fișiere;
  • o pagină generată prin metoda POST nu poate fi salvată ca marcaje;
  • întrerupe conexiunea HTTP;
  • Pentru a transmite chiar și o cantitate foarte mică de informații, majoritatea browserelor trimit cel puțin două pachete TCP: un antet și apoi un corp al cererii.

Se pare că aceste două metode nu sunt atât de asemănătoare. Utilizarea unuia sau altuia ar trebui să fie determinată de sarcina la îndemână și nu de faptul că GET este utilizat în mod implicit sau este mai ușor de lucrat. GET, desigur, este o opțiune mai bună în majoritatea cazurilor, mai ales atunci când construiești AJAX rapid, dar nu uita de dezavantajele sale. Pentru mine, am făcut un algoritm simplu-notă despre alegerea unei metode.