Søger du en specifik kategori?

 



Oprettet ons. d. 11. februar 2009 kl. 11:16

jensgram
jensgram (38.569 point)
www.jensgram.dk
Guidens karaktér
1
2
3
4
5

POST vs. GET i praksis

Denne artikel har til formål at gøre læseren i stand til at afgøre, hvornår man skal benytte POST henholdsvis GET som forespøgselsmetode i forbindelse med HTML-formularer, links og andre forespørgsler. Inledningsvist præsenteres HTTP/1.1 overordnet.
Introduktion
Fra tid til anden bliver der spurgt til, hvornår man bør benytte POST eller GET i en HTML-formular. Ligeledes sker det til tider, at en bruger brokker sig over, at dennes browser beder vedkommende bekræfte, at data skal gensendes for at opdatere en side (via POST). Det er mit mål, at det følgende skal give læseren indblik i filosofien bag POST- og GET-metoderne for derved selv at kunne foretage det rigtige valg (og forstå hvorfor browser beder om bekræftelse).


Hypertext Transfer Protocol
En forespørgsel via HTTP består af en header-sektion og en "krop" (body). Dette kan for så vidt sammenlignes med HTML, hvor metadata forefindes inden for <head>-tagget, mens selve dokumentets indhold er omsluttet af <body>-tagget. For HTTP-protokollen er syntaksen dog noget mere stringent for head-delen:
<Header>: <Data>, hvor hver header står på en linie for sig (afsluttet med CRLF, \r\n).

Head og body adskilles af en blank linie - dvs. to på hinanden følgende linieskift. En simpel forespørgsel på en side kunne se ud som:
HEAD / HTTP/1.1
Host: www.jensgram.dk



Bemærk, at "/" efter HEAD i første linie betyder, at jeg forespørger roden af sitet. Serveren ved, at indekssiden hedder index.php, men det kunne jeg også selv have skrevet. Læg desuden mærke til, at der er en blank linie efter Host-linien - den afslutter head-sektionen (og dermed forespørgslen i dette tilfælde, da HEAD-forspørgsler ikke har nogen body.

Gennem et forespørgselsværktøj (http://mbn.dk/ (...)) afsløres serverens svar:
HTTP/1.1 200 OK
Date: Wed, 10 Jan 2007 12:40:53 GMT
Server: Apache/1.3.33 (Unix) PHP/4.3.11
[headers udeladt til fordel for læsbarhed...]
Content-Type: text/html; charset=iso-8859-1



Bemærk, at der heller ikke her er noget indhold i body-sektionen (det er netop formålet med HEAD-metoden, jf. næste afsnit).

For det følgende, skulle du nu besidde tilstrækkeligt kendskab til HTTP-forspørgslernes natur. Har du appetit på mere så kig i afsnittet "Links til videre læsning" nedenfor.


HTTP & forespørgselsmetoder
I HTTP-protokollen findes 8 forespørgselsmetoder, hvoraf kun følgende 3 er relevante for denne artikels fokus (HEAD er medtaget for ovenstående eksempels skyld):
1) GET: Den almindeligste metode, der beder om indholdet for en given adresse (URI)
2) HEAD: Som GET, dog kun headers (se eksempel ovenfor).
3) POST: Forespørger en ressource - body-sektionen kan indeholde data (fra formularer etc.)

I en GET-forespørgsel kan man medsende data i en såkaldt "query string". Ønsker jeg eksempelvis at søge efter "eksperten" på Google, kan jeg indtaste adressen http://www.google.com/ (...) i min browser, der ved sender en forespørgsel lignende:
GET /search?q=eksperten HTTP/1.1
Host: www.google.com


På hosten www.google.com forespørger man ressourcen search med argumentet "q=eksperten". Dette argument kunne eksempelvis tilgås via $_GET['q'] i PHP, men det er uden for denne artikels fokusområde. Vigtigt er det, at den resulterende side kan findes igen gennem den benyttede URI (hér: URL), da alle data er en del heraf. Dokumentet er således identificébart (selv om de enkelte hits naturligvis kan skifte).

Skulle ovenstående forespørgsel i stedet foretages via POST, ville det se ud som følger:
POST /search HTTP/1.1
Host: www.google.com
Content-Length: 11

q=eksperten

Her ses, at data nu ikke længere er en del af URL'en (http://www.google.com/ (...)), men i stedet udgør forespørgslens body-sektion. Det betyder, at man ikke kan linke til netop denne forespørgsel (søgetermen er ikke en del af URL'en). Desuden svarer Google noget i retning af "The server is unable to process your request.", men det er mindre relevant for nærværende.


Sikre metoder
Sikker interaktion er i HTTP/1.1-specifikationen defineret som interaktion, hvor klienten ikke er "ansvarlig" for sine handlinger. Således er det at følge et link eller at foretage en simpel søgning på eksempelvis Google et eksempel på sikker interaktion. En transaktion via Netbank er derimod ikke sikker, da man som bruger netop kan drages til ansvar for de handlinger man foretager; handlinger, der rent faktisk har en effekt.

Af ovennævnte metoder er HEAD og GET defineret som sikre. Det betyder ikke, at indholdet på en forespurgt URL ikke må ændre sig, men blot at forespørgslen ikke bør ændre serverens tilstand - forespørgslen har ingen sideeffekter. I denne sammehæng er det vigtigt at forstå, at en GET-forespørgsel - eksempelvis http://www.google.com/ (...) - kan afstedkomme forskelligt indhold (eftersom Google får indekseret nye sider, der har tilknytning til "eksperten"). Det essentielle er, at søgningen ikke forårsager ændringer på serveren.

POST-forespørgsler er derimod ikke sikre, da det netop er filosofien, at en sådan må ændre serverens tilstand (tilmelde en bruger til en mailing-liste e.l.). Problemet er imidlertid, at det er op til udviklerne at håndhæve GET-forespørgslens immanente egenskab som sikker metode. Det er altså op til udvikleren at sørge for, at GET-forespørgsler forbliver sikre.

Som en sidebemærkning kan det nævnes, at metoderne GET, HEAD, PUT, DELETE, OPTIONS og TRACE er idempotente. Det betyder, at sideeffekterne for gentagne, identiske forespørgsler er identiske med sideeffekterne for én forespørgsel. PUT og DELETE er idempotente, da en ressource i sagens natur kun kan oprettes eller slettes én gang (der ses bort fra fejlmeddelelser ifm. idempotens). POST er ikke idempotent, hvilket forklarer, at en browser bør bede brugeren bekræfte at POST-data skal sendes igen.


Hvilken metode skal jeg så vælge?
Med udgangspunkt i, at:
a) Enhver ressource er identificérbar via en URI (hér: URL, da vi beskæftiger os med HTTP), og
b) GET benyttes som defineret - i.e. som en sikker metode
skulle det nu være muligt at fastslå, hvornår man skal vælge POST henholdsvis GET.

Du bør benytte GET-metoden, hvis den ønskede interaktion skal tænkes som en forespørgsel på en ressource. Netop herfor er GET den mest benyttede forespørgselsmetode, da almindelig surfing ved at følge hyperlinks netop er en kæde af simple forespørgsler på ressourcer.

Du bør benytte POST-metoden, hvis interaktionen er af en sådan natur, at den kan afstedkomme ændringer på serveren. Det kunne eksempelvis være tilmelding til nyhedsbreve, overførsel af penge via Netbank, bestilling på webshop etc. Vær dog opmærksom på, at der er visse tilfælde, hvor det er acceptabelt at lade GET-forespørgsler ændre tilstand på serveren. Et eksempel kan være en besøgstæller, der inkrementeres for enhver forespørgsel. Den omstændighed, at brugeren ikke er ansvarlig for denne handling, gør, at forespørgslen som sådan stadig er sikker.


Vil det sige, at GET bør være forbeholdt links og POST forbeholdt formularer?
Nej! Det var absolut ikke min hensigt at foranledige læseren til at tro det. Ved at tage udgangspunkt i HTTP's definition, var det en del af mit mål at lade læseren forstå, hvordan både GET- og POST-forespørgsler reelt "ser ud". Dermed skulle det også stå klart, at et hyperlink ikke kan ligge til grund for en POST-forespørgsel.

Det var også en del af min målsætning at vise, at en GET-forespørgsel (og dermed et hyperlink) godt kan benyttes til at ændre tilstand på en server. Det er udviklerens ansvar, at dette ikke er tilfældet.

Hvis en formular ikke forårsager tilstandsændring på serveren, bør du benytte GET. Tænk eksempelvis på søgeformularen på Googles forside (http://www.google.com/), der benytter sig af GET. Det har den positive effekt, at brugere kan kopiere URL'en for en specifik søgning (som ovenfor). Et andet eksempel kunne være en artikel, der består af flere sider, hvor man vil kunne benytte en formular til at tilgå de enkelte sider.


Afslutning
Det er mit håb, at læseren nu har tilegnet sig grundigere forståelse af, hvornår POST før foretrækkes til fordel for GET og vice versa. I ovenstående har jeg ikke været inde på praktiske og sikkerhedsmæssige overvejelser, men appelerer i nogen grad til læserens sunde fornuft. Vigtigst er det nok at være opmærksom på, at det er en skrøne, at POST-forespørgsler skulle være mere sikre eller sværere at eftergøre end GET-forespørgsler. I samme omgang bør det nævnes, at følsomme data aldrig bør være del af en URI.

Med venlig hilsen
- Jens Gram, http://www.jensgram.dk/


Links til videre læsning
- Hypertext Transfer Protocol på Wikipedia: http://en.wikipedia.org/ (...)
- RFC 2612 om HTTP/1.1 fra W3C/MIT: http://rfc.sunsite.dk/ (...)
- URIs, Addressability, and the use of HTTP GET and POST fra W3C: http://www.w3.org/ (...)
- HTTP query tool af Morten Blinksbjerg Nielsen: http://mbn.dk/ (...)


Change log:
2007/01/10: Første version publiceret
2007/01/11: Tyrk-fjel rettet som påpeget af phliplip
2009/03/23: Links rettet til E5

Skrevet tor. d. 11. januar 2007 kl. 00:54| #1

wickedd (15.912 point)
God læsning!

Skrevet tor. d. 11. januar 2007 kl. 09:12| #2


Skrevet tor. d. 11. januar 2007 kl. 12:40| #3

phliplip (17.289 point)
God artikel! Men i ovennævnte sammenhæng skal _POST nok rettes til _GET "Men Dette argument kunne eksempelvis tilgås via $_POST['q'] i PHP"

;)

Skrevet tor. d. 25. januar 2007 kl. 21:48| #4

greew (19.014 point)
Meget brugbar!! Takker! - Jesper

Skrevet tir. d. 13. februar 2007 kl. 19:45| #5

danieru (9.245 point)
Jaja da! ;)

Skrevet fre. d. 16. februar 2007 kl. 11:06| #6


Skrevet man. d. 19. februar 2007 kl. 22:46| #7

amite (19.181 point)
Glimrende artikkel! Omhandlede præcist det den skulle. Man fik rusket op i nogle tanker på et område som man normalt ellers kan have en tendens til at hoppe (for?) let henover. /thumbs_up

Skrevet fre. d. 27. marts 2009 kl. 14:28| #8

jokkejensen (36.005 point)
fiddler2.com er et godt analyse værktøj til IE.

Skriv en kommentar



Mest populære guides

Guidens karakter
!!!Karaktér: 3
12 stemmer
31/01 - 2011
Af: heinzdmx

Dropbox - gratis online lagerplads

Jeg vil i denne guide forklare lidt om hvad Dropbox er og også hvordan du får mest mulig plads på Dropbox. Dropbox er kort sagt en service hvor du har dine data lagt til backup på både nettet og din egen computer.
Guidens karakter
!!!Karaktér: 4
33 stemmer
02/02 - 2009
Af: jkrons

Dato- og tidsberegninger i Excel

En introduktion til simple beregninger med dato og tid i Excel. Opdateret med afsnit om beregning af tillæg.
Excel  |  Læs »
Guidens karakter
!!!Karaktér: 4
21 stemmer
06/11 - 2011
Af: fromsej

Sådan fjerner du virus og malware

Udviklingen går stærkt på "skidt"fronten, så vi har sammensat en ny og effektiv programpakke til fjernelse af det.
Virus  |  Læs »

Log ind

   

   

Seneste guides

Den gode bruger
Adgang til NAS-server via WAN
Kollektion af Batch tutorials (FJERNET)
Tilpas din YouTube afspiller


   




Tips & Tricks fra PC World

Teaser billede

Sådan fjerner du pladskrævende metadata fra dine fotos

Det er langt fra altid, at dine billeders metadata såsom kameramodel og geografisk placering er vigtige at bevare. JPG & PNG Stripper kan luge ud i billedfilerne, så de fylder meget mindre....


Anmeldelser fra PC World

Teaser billede

Test: Superlet bærbar med mange muligheder

Toshiba har med Satellite Z830 skabt en af verdens letteste ultrabooks. Den vejer 1,1 kilo, og computeren på 13 tommer ser på papiret ud til at være en oplagt rejsekammerat. Men den lave vægt har...


Seneste blogindlæg

Teaser billede

Tvangslukke spørgsmål: Hvad er den bedste løsning?

Hej Vi har mange åbne spørgsmål på Eksperten. Vi ville gerne tvangslukke dem - så et spørgsmål efter f.eks. 6 måneder lukkes. Men der er et par uklarheder som ville være gode at få lidt input til:...


Nyheder fra PC World

Teaser billede

Samsung Galaxy S III på vej

Samsungs bedst sælgende smartphone nogensinde får en efterfølger om kort tid.


Nyheder fra Computerworld

Teaser billede

Apple retter hele 51 sikkerhedshuller i Mac OS X

Apple lukker hele 51 sårbarheder i Mac OS X, hvoraf de fleste er kritiske. Se her, hvor hullerne er.


Kurser
Samarbejdspartnere

Udgiver · © 2012 IDG Danmark A/S · Hørkær 18 · 2730 Herlev · Tlf.: 77 300 300 · Fax: 77 300 301 · Brug af personoplysninger