HTTP och JSON
En vanlig webbsida visar det den fick när den laddades. Vill du se något nytt laddar du om den. En webbapplikation som Zulip fungerar annorlunda: nya meddelanden dyker upp utan att sidan laddas om. Det kräver att JavaScript-koden på sidan själv hämtar och skickar data till en server medan sidan är öppen.
Den här artikeln handlar om språket de två talar, HTTP, och formatet datan oftast skickas i, JSON. De två följande artiklarna visar hur du skriver koden som väntar på svaret, Promises och async/await, och hur du gör själva anropet, Nätverksanrop med fetch.
Tidsåtgång: Ungefär 15 minuter.
En förfrågan och ett svar
Section titled “En förfrågan och ett svar”HTTP (Hypertext Transfer Protocol) är samma protokoll som webbläsaren använder när den hämtar
index.html, bilder och stilmallar. Det är byggt på en enkel princip: klienten skickar en
förfrågan (request), och servern skickar tillbaka ett svar (response). Servern tar aldrig
kontakt på eget initiativ.
En förfrågan består av en metod, en URL, ett antal headrar (headers) och ibland en body:
POST /books HTTP/1.1Host: api.example.comContent-Type: application/jsonAccept: application/json
{ "title": "Hemsöborna", "author": "August Strindberg" }Svaret består av en statuskod, headrar och oftast en body:
HTTP/1.1 201 CreatedContent-Type: application/jsonLocation: /books/43
{ "id": 43, "title": "Hemsöborna", "author": "August Strindberg" }Headrarna är metadata om meddelandet. Content-Type talar om vilket format bodyn har, och Accept
vilket format klienten vill ha tillbaka. Bodyn är själva innehållet.
Du kan se varje förfrågan och varje svar själv. Öppna utvecklarverktygen, välj fliken Network och ladda om sidan. Klickar du på en rad ser du metod, statuskod, headrar och body, både det som skickades och det som kom tillbaka. Det är det första stället att titta på när en förfrågan inte gör det du väntar dig.
Metoder
Section titled “Metoder”Metoden talar om vad klienten vill göra med resursen som URL:en pekar ut:
| Metod | Betydelse | Har en body |
|---|---|---|
GET |
Hämta resursen. | Nej |
POST |
Skapa en ny resurs eller skicka data. | Ja |
PUT |
Ersätt resursen helt. | Ja |
PATCH |
Ändra en del av resursen. | Ja |
DELETE |
Ta bort resursen. | Nej |
GET ändrar ingenting på servern. Därför kan webbläsaren skicka om, hämta i förväg och cacha
GET-förfrågningar utan risk. En POST kan däremot göra något som inte ska hända två gånger, som
att lägga en beställning.
Ett HTML-formulär kan bara skicka GET och POST. Med JavaScript kan du använda alla metoder.
Data i URL:en eller i bodyn
Section titled “Data i URL:en eller i bodyn”En GET har ingen body. Behöver servern veta något skickas det i URL:en, som en query string
efter ?:
GET /books?author=Strindberg&sort=year HTTP/1.1Med POST, PUT och PATCH skickas datan i bodyn.
Fråga: är POST säkrare än GET?
Section titled “Fråga: är POST säkrare än GET?”Ett formulär för inloggning skickar lösenordet med POST i stället för GET. Är lösenordet därmed
skyddat på vägen till servern?
Nej. Med GET hamnar lösenordet i URL:en, och därmed i webbläsarens historik, i serverns loggar
och synligt för den som tittar över axeln. Det är skäl nog att använda POST. Men på vägen till
servern är bodyn lika läsbar som URL:en för den som kan avlyssna trafiken.
Det som skyddar datan på vägen är HTTPS, som krypterar hela förfrågan, både URL, headrar och body. Det gäller oavsett metod.
Statuskoder
Section titled “Statuskoder”Varje svar har en statuskod. Den första siffran säger vilken sorts svar det är:
- 2xx – det lyckades.
200 OK,201 Created(en resurs har skapats) och204 No Content(det lyckades, men det finns ingen body). - 3xx – resursen finns någon annanstans eller har inte ändrats.
301 Moved Permanentlyoch304 Not Modified. Webbläsaren hanterar dem själv: den följer omdirigeringen, eller använder sin sparade kopia. - 4xx – felet ligger i förfrågan.
400 Bad Request(förfrågan är felaktig),401 Unauthorized(du måste logga in),403 Forbidden(du får inte),404 Not Foundoch415 Unsupported Media Type(servern förstår inte formatet i bodyn). - 5xx – felet ligger hos servern.
500 Internal Server Erroroch503 Service Unavailable.
Läs alltid statuskoden innan du använder bodyn. Ett svar med 404 har ofta en body också, men den
innehåller ett felmeddelande, inte det du bad om.
Statuskoden säger hur det gick på HTTP-nivå, och inte nödvändigtvis hur det gick för det du ville
göra. Wikipedias API, som veckans övningsuppgift använder, svarar 200 OK även när artikeln du söker
inte finns, och berättar det i stället i bodyn. Hur ett API använder statuskoderna står i dess
dokumentation, eller syns när du provar.
Fråga: vems är felet?
Section titled “Fråga: vems är felet?”Din kod skickar JSON i bodyn på en POST, men glömmer headern Content-Type. Servern svarar
415 Unsupported Media Type. Är det ett fel i servern?
Nej, det är ett fel i förfrågan, vilket 4 i början också säger. Utan Content-Type vet servern inte
att bodyn är JSON, och den gissar inte. Den svarar att den inte kan hantera formatet.
En kod i 4xx-serien betyder i regel att det inte hjälper att skicka samma förfrågan igen. Något i den måste ändras. En kod i 5xx-serien kan däremot gå över av sig själv.
Resurser och länkar
Section titled “Resurser och länkar”Ett API där varje sak har en egen URL och metoderna betyder det de ska kallas ofta REST-API
(Representational State Transfer). GET /books/42 hämtar bok 42, DELETE /books/42 tar bort den och
POST /books skapar en ny. Du behöver inte lära dig ett nytt litet språk för varje API, eftersom
metoderna redan säger vad som ska göras.
Många API:er skickar också med länkar i svaret, till det du kan göra härnäst:
{ "id": 42, "title": "Röda rummet", "_links": { "self": { "href": "https://api.example.com/books/42" }, "author": { "href": "https://api.example.com/authors/7" } }}Klienten följer länken i stället för att själv bygga ihop URL:en. Flyttar servern sina resurser fortsätter klienten att fungera, eftersom den aldrig har räknat ut URL:erna på egen hand. API:et i examinationsuppgift B2 fungerar på det sättet.
Bodyn i svaren ovan är skriven i JSON (JavaScript Object Notation), det format nästan alla
webb-API:er använder i dag. Det ser ut som JavaScript, men är ett eget textformat med strängare regler,
så att det kan läsas av vilket programspråk som helst. MIME-typen är application/json.
JSON har sex datatyper: strängar, tal, true och false, null, objekt och arrayer.
{ "title": "Röda rummet", "year": 1879, "available": true, "translator": null, "tags": ["roman", "satir"]}Jämfört med ett objekt i JavaScript:
- Nycklar och strängar skrivs alltid med dubbla citattecken.
{ title: 'Röda rummet' }är giltig JavaScript men inte giltig JSON. - Inget kommatecken efter sista elementet, och inga kommentarer.
- Inga funktioner, ingen
undefinedoch inga datum. Ett datum skickas som en sträng, vanligen i formatet"2026-11-02T10:15:00Z".
Från text till objekt och tillbaka
Section titled “Från text till objekt och tillbaka”JSON.parse() tolkar en JSON-sträng och skapar motsvarande värde i JavaScript. JSON.stringify() gör
det omvända:
const text = '{ "title": "Röda rummet", "year": 1879 }'
const book = JSON.parse(text)console.log(book.year) // 1879
const json = JSON.stringify(book)console.log(json) // {"title":"Röda rummet","year":1879}Döp variabeln efter vad den innehåller. Det som kommer ur JSON.parse() är en bok, inte JSON, och
heter därför book. Bara strängen är JSON.
JSON.stringify() skriver allt på en rad. Vill du läsa resultatet själv, till exempel i konsolen,
kan du be om indrag: JSON.stringify(book, null, 2).
Fråga: vad blir kvar?
Section titled “Fråga: vad blir kvar?”const author = { name: 'August Strindberg', born: new Date('1849-01-22'), nickname: undefined, greet() { return `Hello, my name is ${this.name}.` }}
const copy = JSON.parse(JSON.stringify(author))Vilka egenskaper har copy, och vad är copy.born för något?
copy har bara name och born.
JSON.stringify() hoppar över egenskaper vars värde är en funktion eller undefined, eftersom
JSON saknar motsvarighet. Det blir inget fel; egenskaperna försvinner bara. Ett datum görs om till en
sträng, och JSON.parse() vet inte att strängen en gång var ett datum. copy.born är alltså
strängen "1849-01-22T00:00:00.000Z", inte ett Date-objekt. Behöver du ett datum får du skapa det
själv: new Date(copy.born).
Det är också därför JSON.parse(JSON.stringify(x)) är ett dåligt sätt att kopiera objekt. Använd
structuredClone(x), som klarar datum och mycket annat.
När tolkningen misslyckas
Section titled “När tolkningen misslyckas”JSON.parse() kastar ett SyntaxError om texten inte är giltig JSON. Det händer oftare än man tror,
eftersom data från en server inte alltid är det du väntar dig. Ett vanligt fall är att servern svarar
med en HTML-sida, till exempel en felsida, när du väntade dig JSON. Felmeddelandet ser då ut ungefär
så här:
SyntaxError: Unexpected token '<', "<!DOCTYPE "... is not valid JSONTecknet < är början på <!DOCTYPE html>. Ser du det meddelandet är felet sällan i din tolkning,
utan i att du fick fel sorts svar. Titta på förfrågan i fliken Network: vilken statuskod fick du,
och till vilken URL gick förfrågan?
JSON.stringify() misslyckas sällan. Det kastar ett TypeError om objektet refererar till sig
självt, direkt eller via andra objekt, eller om det innehåller ett BigInt.
JSON.parse() och JSON.stringify() är synkrona. Det märks inte för vanliga svar, men en mycket stor
sträng tar tid att tolka, och under tiden står huvudtråden still, som du såg i
Händelseloopen. Nätverksanropet som hämtar
strängen är däremot asynkront, och det är ämnet för nästa artikel.
Att ta med sig
Section titled “Att ta med sig”- En förfrågan har en metod, en URL, headrar och ibland en body. Ett svar har en statuskod, headrar och oftast en body. Fliken Network visar allt.
GEThämtar och ändrar ingenting.POST,PUT,PATCHochDELETEändrar något på servern.- Läs statuskoden innan du använder bodyn: 2xx lyckades, 4xx är fel i förfrågan och 5xx är fel hos servern. Läs också hur API:et du använder rapporterar fel.
Content-Typetalar om formatet på bodyn. Skickar du JSON ska headern varaapplication/json.- JSON är text med dubbla citattecken, sex datatyper och inga funktioner eller datum.
JSON.parse()kan kasta ettSyntaxError.
Vidare läsning
Section titled “Vidare läsning”- Läsanvisningarna för veckan, i synnerhet kapitel 11.6 i kursboken om JSON.
- An overview of HTTP och HTTP response status codes på MDN.
- JSON på MDN och json.org, som beskriver hela formatet på en sida.