Utviklere

Hva er JSON? Syntaksregler og vanlige feil forklart

7 min lesetid

JSON (JavaScript Object Notation) er et tekstformat for strukturerte data, bygget opp av nøkkel-verdi-par og ordnede lister, med bare seks verdityper å forholde seg til. Det er formatet nesten alle web-API-er bruker til å sende og motta data, og det dukker like ofte opp i konfigurasjonsfiler, loggrader og NoSQL-databaser. JSON ligner et JavaScript-objektlitteral på overflaten, men har et lite og strengt regelsett, og bryter du én eneste av reglene blir hele dokumentet umulig å lese for en parser.

Hva JSON egentlig er

Hvert JSON-dokument er bygget av nøyaktig seks verdityper:

  • Streng, kun med doble anførselstegn, som "hei"
  • Tall, som 42 eller 3.14
  • Boolsk verdi, enten true eller false
  • null
  • Objekt, en uordnet samling nøkkel-verdi-par pakket inn i {}
  • Array, en ordnet liste med verdier pakket inn i []

Det er hele typesystemet. Det finnes ingen egen datotype, ingen undefined, ingen funksjonstype, ingenting annet. Objekter og arrays kan nøstes i hverandre så dypt du vil, men enhver verdi på ethvert nivå må være en av disse seks.

Syntaksreglene som følger med disse typene er like faste:

  • Nøkler i et objekt må være strenger med doble anførselstegn. {"navn":"Ada"} er gyldig, {navn:"Ada"} er det ikke.
  • Ingen komma etter siste element. Den siste egenskapen i et objekt og det siste elementet i en array kan ikke ha komma etter seg.
  • Ingen kommentarer av noe slag, verken // eller /* */.
  • Strenger og nøkler bruker kun doble anførselstegn. Enkle anførselstegn er ikke gyldig JSON-syntaks, selv om de er gyldige i JavaScript.
  • Nøkler kan aldri stå uten anførselstegn, uansett hvor enkelt navnet er.
  • NaN, Infinity og undefined er ikke gyldige JSON-verdier, selv om alle tre er gyldige i JavaScript.
  • Funksjoner kan ikke representeres i JSON. Det finnes ingen måte å serialisere atferd på, bare data.

Bryter du én av disse reglene, stopper en JSON-parser opp og rapporterer en feil i stedet for å gjette hva du mente.

JSON kontra et JavaScript-objektlitteral

JSONs {}- og []-syntaks er lånt fra JavaScripts objekt- og array-literaler, og det er nettopp derfor de to blir forvekslet. De ser nesten identiske ut på skjermen, men et JavaScript-objektlitteral er mer tillatende på hvert eneste punkt der JSON er strengt:

EgenskapJSONJavaScript-objektlitteral
Nøkler må ha anførselstegnJa, kun dobleNei, valgfritt
Komma etter siste element tillattNeiJa
Kommentarer tillattNeiJa
Enkle anførselstegn i strengerNeiJa
Funksjoner som verdierNeiJa
undefined som verdiNeiJa

Dette er der mye feilsøkingstid går tapt. Kopierer du et objektlitteral rett ut av en JavaScript-fil, med uanførte nøkler, komma etter siste element og alt, inn i et felt som forventer JSON, får du noe som kjører fint som JavaScript men feiler i det øyeblikket JSON.parse rører ved det. JSON er ikke en delmengde av JavaScript-syntaks du kan skrive løst, det er et eget, strengere format som tilfeldigvis deler tegnsetting med ett.

Praktisk eksempel: minifisere og formatere et ekte API-svar

Ta et typisk brukerobjekt et API kan returnere:

{
  "id": 1,
  "name": "Ada Lovelace",
  "email": "[email protected]",
  "roles": [
    "admin",
    "user"
  ],
  "active": true,
  "meta": null
}

Den pent formaterte versjonen, med 2 mellomroms innrykk, er 145 tegn lang. Samme data minifisert, med hvert mellomrom og linjeskift fjernet, ser slik ut:

{"id":1,"name":"Ada Lovelace","email":"[email protected]","roles":["admin","user"],"active":true,"meta":null}

Det er 107 tegn, omtrent 35 % mindre, og hele forskjellen kommer fra whitespace alene. Ikke én eneste verdi eller nøkkel er endret, dataene er identiske.

Det er derfor API-er sender JSON minifisert over nettet: i stor skala utgjør de sparte 35 % av bytene, på tvers av millioner av forespørsler, reell båndbredde og lavere ventetid, og ingen klientkode trenger innrykket for å tolke verdien riktig. Men den samme minifiserte strengen er nesten uleselig for et menneske. Feilsøker du et svar og trenger å se nøstingen, nøkkelnavnene og hvor en array starter og slutter, formaterer du den tilbake til den innrykkede versjonen. Samme data, to forskjellige jobber: én for maskiner, én for deg.

Formater din egen JSON

Lim inn minifisert eller rotete JSON under for å se den omformatert med korrekt innrykk, eller bruk verktøyet motsatt vei for å minifisere et pent formatert dokument før du sender det et sted hvor størrelsen teller.

JSON-formatering og validering
Gratis, ingen registrering, fungerer på alle enheter.
Åpne hele verktøyet

Vanlige feil og spesialtilfeller

Komma etter siste element. Gitt {"id":1,"name":"Ada",}, rapporterer V8 (motoren bak Chrome og Node.js):

Expected double-quoted property name in JSON at position 21 (line 1 column 22)

Kommaet etter "Ada" har ingenting etter seg, og JSON har ingen forestilling om et valgfritt avsluttende skilletegn. Firefox sin SpiderMonkey-motor formulerer feilmeldingene sine annerledes, men parsingen feiler på samme måte i enhver JSON-kompatibel motor.

Uanførte nøkler. {id:1} feiler med:

Expected property name or '}' in JSON at position 1 (line 1 column 2)

Parseren forventer en streng med doble anførselstegn rett etter { og finner i stedet en ren identifikator.

Nøkler med enkle anførselstegn. {'a':1} treffer samme feilklasse:

Expected property name or '}' in JSON at position 1 (line 1 column 2)

Enkle anførselstegn er ikke en gyldig måte å åpne en streng på i JSON, så parseren behandler 'a' nøyaktig som den ville behandlet en uanført nøkkel: ikke et gyldig egenskapsnavn.

NaN og undefined som verdier. {"a":NaN} gir:

Unexpected token 'N', "{"a":NaN}" is not valid JSON

Og {"a":undefined} gir:

Unexpected token 'u', "{"a":undefined}" is not valid JSON

Begge er lovlige i et JavaScript-objektlitteral, men har ingen representasjon i JSON. Kan en verdi bli NaN eller undefined i applikasjonen din, må du konvertere den til null eller en streng før du serialiserer.

Duplikate nøkler blir overskrevet uten varsel. {"a":1,"a":2} er syntaktisk gyldig JSON, ingen feil i det hele tatt, og parses til {"a":2}. De fleste parsere, inkludert JavaScripts egen, beholder kun den siste forekomsten av en gjentatt nøkkel og forkaster den forrige uten advarsel. Dette er en snikende kilde til reelle feil: et byggeverktøy som setter sammen konfigurasjonsfragmenter, eller en håndredigert fil der noen limer inn en blokk to ganger, kan ende opp med samme nøkkel to steder, og fordi det ikke oppstår noen feil, oppdager ingen det før feil verdi dukker opp lenger nede i systemet.

Ofte stilte spørsmål

Hva er JSON? JSON (JavaScript Object Notation) er et tekstformat for strukturerte data, bygget på seks verdityper: strenger, tall, boolske verdier, null, objekter og arrays. Det er det vanligste formatet for API-forespørsler og -svar, og det brukes også i konfigurasjonsfiler og mange databaser.

Er JSON det samme som et JavaScript-objekt? Nei. JSON ser ut som et JavaScript-objektlitteral, men er strengere: nøkler må ha doble anførselstegn, komma etter siste element er ikke tillatt, kommentarer er ikke tillatt, og verdier som undefined eller en funksjon kan ikke representeres i det hele tatt. Et JavaScript-objektlitteral tillater alt dette, JSON tillater ingenting av det.

Hvorfor ødelegger et ekstra komma JSON-en min? Fordi JSONs grammatikk ikke har noen regel for et ekstra komma etter det siste elementet i et objekt eller en array. En parser som leser {"id":1,"name":"Ada",} forventer et nytt egenskapsnavn etter kommaet og finner i stedet den avsluttende klammeparentesen, som er akkurat det feilmeldingen «Expected double-quoted property name in JSON» rapporterer.

Støtter JSON kommentarer? Nei. Det finnes ingen syntaks for //- eller /* */-kommentarer noe sted i JSON-spesifikasjonen. Trenger du å kommentere en JSON-fil for mennesker, er de vanlige løsningene en egen dokumentasjonsfil, en "_comment"-nøkkel som behandles som vanlig data, eller å bytte til et format som faktisk støtter kommentarer, som JSON5 eller YAML.

Hva er forskjellen mellom å formatere og minifisere JSON? Å formatere (også kalt «beautify» eller «prettify») legger til innrykk og linjeskift slik at et menneske kan lese strukturen på et blunk. Å minifisere fjerner all den whitespacen for å produsere kortest mulig streng. Begge representerer nøyaktig de samme dataene, forskjellen er ren presentasjon, og det er vanlig å konvertere mellom de to avhengig av om JSON-en skal leses av en person eller sendes over et nettverk.

Blir dataene mine sendt til en server når jeg bruker en nettbasert formaterer? Med pluri.tools sin JSON-formatering, nei. Formatering, minifisering og validering skjer med vanlig JSON.parse og JSON.stringify i nettleserens JavaScript-motor. Det gjøres ingen fetch eller nettverkskall, så JSON-en du limer inn forlater aldri enheten din.

JSON-formatering og validering
Prøv det nå selv med hele verktøyet.
Prøv nå