HTTP är det protokoll som gör att vi kan köpa mikrovågsugnar från Amazon.com, återförenas med en gammal vän i en Facebook-chatt och titta på roliga kattvideor på YouTube. HTTP är protokollet bakom World Wide Web. Det tillåter en webbserver från ett datacenter i USA att skicka information till ett internetkafé i Australien där en ung student kan läsa en webbsida som beskriver Ming-dynastin i Kina.
I den här boken tittar vi på HTTP från en programvaruutvecklare. Att ha en god förståelse för HTTP kan hjälpa dig att skriva bättre webbapplikationer och webbtjänster. Det kan också hjälpa dig att felsöka program och tjänster när saker går fel. Vi kommer att täcka alla grunder, inklusive resurser, meddelanden, anslutningar och säkerhet i samband med HTTP.
Vi börjar med att titta på resurser.
Kanske är den mest kända delen av webben HTTP-adressen. När jag vill hitta ett recept på en maträtt med broccoli, vilket är nästan aldrig, kan jag öppna min webbläsare och ange http://food.com
i adressfältet för att gå till food.com-webbplatsen och leta efter recept. Min webbläsare förstår denna syntax och vet att den behöver göra en HTTP-begäran till en server som heter food.com. Vi pratar senare om vad det innebär att "göra en HTTP-begäran" och alla berörda nätverksdetaljer. För nu vill vi bara fokusera på adressen: http://food.com
.
Adressen http://food.com
är vad vi kallar en URL-en enhetlig resurslokaliserare. Det representerar en specifik resurs på webben. I detta fall är resursen hemsidan för food.com-webbplatsen. Resurser är saker jag vill interagera med på webben. Bilder, sidor, filer och videor är alla resurser.
Det finns miljarder, om inte trillioner, platser att gå på Internet-med andra ord, det finns trillioner resurser. Varje resurs kommer att ha en webbadress som jag kan använda för att hitta den. http://news.google.com
är en annan plats än http://news.yahoo.com
. Det här är två olika namn, två olika företag, två olika webbplatser och därmed två olika webbadresser. Det kommer givetvis också att finnas olika webbadresser på samma webbplats. http://food.com/recipe/broccoli-salad-10733/
är webbadressen för en sida med en broccoli sallad recept, medan http://food.com/recipe/grilled-cauliflower-19710/
är fortfarande på food.com, men är en annan resurs som beskriver ett blomkål recept.
Vi kan bryta den sista webbadressen i tre delar:
http
, delen före : //
, är vad vi kallar URL-schema. Schemat beskriver på vilket sätt för att komma åt en viss resurs, och i det här fallet berättar webbläsaren att använda hypertextöverföringsprotokollet. Senare tittar vi också på ett annat schema, HTTPS, vilket är det säkra HTTP-protokollet. Det kan hända att du även stöter på andra system, till exempel FTP för filöverföringsprotokollet och mailto för e-postadresser. Allt efter : //
kommer att vara specifikt för ett visst system. Så, en juridisk HTTP-URL kanske inte är en juridisk mailto URL-de två är inte riktigt utbytbara (vilket är meningsfullt eftersom de beskriver olika typer av resurser).
food.com
är värd. Detta värdnamn berättar för webbläsaren namnet på datorn som är värd för resursen. Datorn kommer att använda domännamnssystemet (DNS) för att översätta food.com
till en nätverksadress, och då kommer den att veta exakt var du ska skicka begäran om resursen. Du kan också ange värddelen av en webbadress med en IP-adress./ Recept / grillad-blomkål-19710 /
är URL-sökväg. Food.com-värd ska känna igen den specifika resurs som begärs av den här sökvägen och svara på lämpligt sätt.Ibland pekar en URL på en fil på värdens filsystem eller hårddisk. Till exempel URL-adressen http://food.com/logo.jpg
kan peka på en bild som verkligen finns på food.com-servern. Resurser kan dock också vara dynamiska. URL: n http://food.com/recipes/brocolli
refererar nog inte till en riktig fil på food.com-servern. I stället kör någon typ av program på hosten värd.com som tar den förfrågan och bygger en resurs med hjälp av innehåll från en databas. Applikationen kan byggas med ASP.NET, PHP, Perl, Ruby on Rails eller någon annan webbteknologi som vet hur man svarar på inkommande förfrågningar genom att skapa HTML för en webbläsare att visa.
I själva verket försöker många webbplatser idag undvika ha någon form av äkta filnamn i deras URL. För att börja med är filnamn vanligtvis associerade med en specifik teknik, som .aspx för Microsofts ASP.NET-teknik. Många webbadresser kommer att överleva den teknik som används för att vara värd för och tjäna dem. För det andra vill många webbplatser placera sökord i en webbadress (som att ha / Recept / broccoli /
i URL-adressen för ett broccolirecept). Att ha dessa nyckelord i webbadressen är en form av sökmotoroptimering (SEO) som kommer att rangordna resursen högre i sökmotorresultaten. Beskrivande nyckelord, inte filnamn, är viktiga för webbadresser dessa dagar.
Vissa resurser leder också till att webbläsaren laddar ner ytterligare resurser. Food.com hemsida kommer att innehålla bilder, JavaScript-filer, CSS och andra resurser som alla kommer att kombinera för att presentera "home page" of food.com.
food.com hemsidaNu när vi vet om webbadresser, värdar och sökvägar, låt oss också titta på en webbadress med ett portnummer:
http://food.com:80/recipes/broccoli/
Numret 80 representerar portnummer värden använder för att lyssna på HTTP-förfrågningar. Standardportnumret för HTTP är port 80, så du ser i allmänhet detta portnummer ut från en webbadress. Du behöver bara ange ett portnummer om servern lyssnar på en annan port än port 80, som vanligtvis bara händer i testning, felsökning eller utvecklingsmiljöer. Låt oss titta på en annan webbadress.
http://www.bing.com/search?q=broccoli
Allt efter ?
(frågetecknet) är känt som fråga. Frågan, även kallad frågesträng, innehåller information för destinationswebbplatsen att använda eller tolka. Det finns ingen formell standard för hur frågesträngen ska se ut som det är tekniskt upp till applikationen för att tolka de värden som den finner men du ser att de flesta frågesträngor som används för att passera namnvärdespar i formuläret namn1 = värde1 & namn2 = värde2
.
Till exempel:
http://foo.com?first=Scott&last=Allen
Det finns två namnvärdespar i det här exemplet. Det första paret har namnet "först" och värdet "Scott". Det andra paret heter "sista" med värdet "Allen". I vår tidigare URL (http://www.bing.com/search?q=broccoli
) kommer Bing-sökmotorn att se namnet "q" som är associerat med värdet "broccoli". Det visar sig att Bing-motorn letar efter ett "q" -värde att använda som sökord. Vi kan tänka på URL-adressen som URL-adressen för resursen som representerar Bing-sökresultaten för broccoli.
Slutligen en ytterligare URL:
http://server.com?recipe=broccoli#ingredients
Del efter # -skylten är känd som fragment. Fragmentet är annorlunda än de andra bitarna vi hittills har tittat på, eftersom det i motsats till URL-sökvägen och frågesträngen inte behandlas av servern. Fragmentet används endast på klienten och det identifierar en viss del av en resurs. Specifikt används fragmentet typiskt för att identifiera ett specifikt HTML-element i en sida av elementets ID.
Webbläsare justerar vanligen den ursprungliga skärmen på en webbsida så att toppen av elementet som identifieras av fragmentet ligger högst upp på skärmen. Som ett exempel, URL: en http://odetocode.com/Blogs/scott/archive/2011/11/29/programming-windows-8-the-sublime-to-the-strange.aspx#feedback
har fragmentvärdet "återkoppling". Om du följer webbadressen ska din webbläsare bläddra ner på sidan för att visa återkopplingsdelen av ett visst blogginlägg på min blogg. Din webbläsare hämtade hela resursen (blogginlägget), men fokuserade din uppmärksamhet på ett visst område-återkopplingsdelen. Du kan tänka dig att HTML för blogginlägget ser ut som följande (med all textinnehåll utelämnad):
......
Klienten ser till att elementet med "feedback" -identifikationen är högst upp.
Om vi sammanställer allt vi har lärt oss hittills vet vi att en webbadress är uppdelad i följande bitar:
: // : / ? #
Alla programutvecklare som arbetar med webben bör vara medvetna om teckenkodningsproblem med webbadresser. De officiella dokumenten som beskriver webbadresser går i stor utsträckning för att göra webbadresser så användbara och driftskompatibla som möjligt. En webbadress ska vara lika lätt att kommunicera via e-post eftersom den ska skriva ut på en bildekal och anbringa en 2001 Ford Windstar. Av denna anledning definierar Internetstandarden osäkra tecken för webbadresser. Mellanslags karaktär anses till exempel vara osäker eftersom rymdtecken felaktigt kan visas eller försvinna när en webbadress är i tryckt form (är det ett mellanslag eller två mellanslag på ditt visitkort?).
Andra osäkra tecken innehåller nummer teckenet (#) eftersom det används för att avgränsa ett fragment och caret (^) eftersom det inte alltid överförs korrekt via alla nätverksenheter. Faktum är att RFC 3986 ("lagen" för webbadresser) definierar de säkra tecknen för webbadresser som de alfanumeriska tecknen i US-ASCII, plus några specialtecken som kolon (:) och slash markeringen (/).
Lyckligtvis kan du fortfarande överföra osäkra tecken i en webbadress, men alla osäkra tecken måste vara procentkodade (aka URL-kodade). % 20
är kodningen för ett mellanslag (där 20 är det hexadecimala värdet för US-ASCII-mellanslag).
Låt oss till exempel säga att du ville skapa webbadressen för en fil med namnet "^ my resume.txt" på someserver.com. Den lagliga kodade webbadressen ser ut som:
http://someserver.com/%5Emy%20resume.txt
Både ^ och mellanslag har varit procentkodade. De flesta webbapplikationsramar kommer att ge ett API för enkel URL-kodning. På serverns sida borde du köra dina dynamiskt skapade webbadresser via ett kodnings API bara om en av de osäkra tecknen visas i webbadressen.
Hittills har vi fokuserat på webbadresser och förenklat allt annat. Men vad betyder det när vi anger en webbadress i webbläsaren? Vanligtvis betyder det att vi vill hämta eller se lite resurs. Det finns en enorm mängd material att se på webben, och senare ser vi också hur HTTP gör det möjligt för oss att skapa, ta bort och uppdatera resurser. För närvarande håller vi fokus på återhämtning.
Vi har inte varit mycket specifika om vilka typer av resurser vi vill hämta. Det finns tusentals olika resurstyper på webbbilderna, hypertextdokument, XML-dokument, video, ljud, körbara applikationer, Microsoft Word-dokument och otaliga fler.
För att en värd ska kunna tjäna en resurs korrekt, och för att en klient ska kunna visa en resurs, måste de berörda parterna vara specifika och exakta om resursens typ. Är resursen en bild? Är resursen en film? Vi vill inte att våra webbläsare ska försöka göra en PNG-bild som text och vi vill inte att de ska försöka tolka hypertext som en bild.
När en värd svarar på en HTTP-begäran returnerar den en resurs och anger även innehållstyp (även känd som medietypen) av resursen. Vi får se detaljerna om hur innehållstypen visas i ett HTTP-meddelande i nästa kapitel.
För att ange innehållstyper, beror HTTP på MIME-standarderna (Multipurpose Internet Mail Extensions). Även om MIME ursprungligen är utformad för e-postkommunikation använder HTTP MIME-standarder för samma ändamål, vilket är att märka innehållet på ett sådant sätt att kunden kommer att veta vad innehållet innehåller.
Till exempel, när en klient begär en HTML-webbsida kan värden svara på HTTP-förfrågan med viss HTML som den markerar som "text / html
"."text
"del är den primära medietypen och"html
"är mediesubtypen. När du svarar på begäran om en bild kommer värden att märka resursen med en innehållstyp av"image / jpeg
"för JPG-filer"image / gif
"för GIF-filer, eller"image / png
"för PNG-filer. Dessa innehållstyper är vanliga MIME-typer och är bokstavligen vad som kommer att visas i HTTP-svaret.
Du kanske tror att en webbläsare skulle förlita sig på filtillägget för att bestämma innehållstypen för en inkommande resurs. Om till exempel, om min webbläsare begär "frog.jpg" ska den behandla resursen som en JPG-fil, men behandla "frog.gif" som en GIF-fil. För de flesta webbläsare är filtillägget det sista stället som kommer att gå för att bestämma den aktuella innehållstypen.
Filförlängningar kan vara vilseledande, och bara för att vi begärde en JPG-fil betyder inte att servern måste svara med data som är kodad i JPG-format. Microsoft dokumenterar Internet Explorer (IE) som först tittar på innehållstypstaggen specificerad av värden. Om värden inte tillhandahåller en innehållstyp kommer IE sedan att skanna de första 200 bytesna av svaret som försöker gissa innehållstypen. Slutligen, om IE inte hittar en innehållstyp och inte kan gissa innehållstypen, kommer den att falla tillbaka på filförlängningen som används i begäran om resursen. Detta är en anledning till att innehållstypeniketten är viktig, men den är långt ifrån den enda anledningen.
Även om vi tenderar att tänka på HTTP som någonting som används för att betjäna webbsidor, visar det sig att HTTP-specifikationen beskriver ett flexibelt, generiskt protokoll för att flytta information om högkvalitativ information. En del av jobbet för att flytta informationen runt är att se till att alla berörda parter vet hur de ska tolka informationen, och det är därför mediatypens inställningar är viktiga.
Mediatyper är dock inte bara för värdar. Kunder kan spela en roll i vilken mediatyp som en värd returnerar genom att delta i en förhandling av innehållstyp.
En resurs identifierad av en enda webbadress kan ha flera representationer. Ta till exempel broccolreceptet som vi nämnde tidigare. Det enda receptet kan ha representationer på olika språk (engelska, franska och tyska). Receptet kan till och med ha representationer i olika format (HTML, PDF och vanlig text). Det är samma resurs och samma recept, men olika representationer.
Den uppenbara frågan är: Vilken representation ska servern välja? Svaret finns i innehållsförhandlingsmekanismen som beskrivs av HTTP-specifikationen. När en klient gör en HTTP-förfrågan till en URL-adress kan klienten ange vilka medietyper det ska acceptera. Medietyperna är inte bara för värden att tagga utgående resurser, men också för kunder att ange den mediatyp de vill konsumera.
Klienten anger vad den accepterar i meddelandet om utgående förfrågan. Återigen ser vi detaljer om det här meddelandet i nästa session, men föreställ dig en förfrågan till http://food.com/
säger att det kommer att acceptera en representation på det tyska språket. Det är upp till servern att försöka uppfylla förfrågan. Värdan kan skicka en textresurs som fortfarande är på engelska, vilket förmodligen kommer att göra en besvikelse för en tysktalande användare, men det är därför vi kallar det innehållsförhandling och inte innehållet ultimatum.
Webbläsare är sofistikerade programvaror som kan hantera många olika typer av resursrepresentationer. Innehållsförhandlingar är något som en användare troligtvis aldrig bryr sig om, men för programutvecklare (särskilt webbtjänstutvecklare) är innehållsförhandling en del av vad som gör HTTP bra. Ett stycke kod skrivet i JavaScript kan göra en förfrågan till servern och be om en JSON-representation. Ett stycke kod skrivet i C ++ kan göra en förfrågan till servern och be om en XML-representation. I båda fallen, om värden kan tillgodose begäran, kommer informationen att komma till kunden i ett idealformat för analysering och konsumtion.
Vid denna tidpunkt har vi gått så långt vi kan gå utan att komma in i de nitty-gritty detaljerna av vad ett HTTP-meddelande ser ut. Vi har lärt oss om webbadresser, URL-kodning och innehållstyper. Det är dags att se vad dessa innehållstypspecifikationer ser ut som de reser tvärs över ledningen.