ToolHub
View All Posts

Najlepsze praktyki formatowania JSON

JSON (JavaScript Object Notation) stał się de facto standardem wymiany danych w sieci Web. API zwracają JSON, pliki konfiguracyjne używają JSON, a nawet bazy danych przechowują dokumenty JSON. Mimo swojej prostoty, JSON ma ścisłe reguły składniowe, które łatwo naruszyć, a nieprawidłowo sformatowany JSON prowadzi do trudności w debugowaniu, problemów z wydajnością i luk bezpieczeństwa. Ten przewodnik obejmuje wszystko, co musisz wiedzieć o prawidłowym formatowaniu JSON, od podstawowej składni po zaawansowane tematy, takie jak walidacja Schema i obsługa dużych plików.

Czym jest JSON?

JSON to lekki, tekstowy format wymiany danych wywodzący się ze składni literałów obiektowych JavaScript. Został określony przez Douglasa Crockforda na początku lat 2000 i standaryzowany jako ECMA-404 i RFC 8259. Cele projektowe JSON to prostota, czytelność dla człowieka i łatwość implementacji w różnych językach programowania. Dziś każdy główny język programowania zawiera wbudowane wsparcie dla JSON.

JSON obsługuje sześć typów danych: stringi (w cudzysłowach), liczby (całkowite i zmiennoprzecinkowe), wartości boolowskie (true i false), null, obiekty (nieuporządkowane kolekcje klucz-wartość) i tablice (uporządkowane listy). Nie obsługuje natywnie komentarzy, dat, danych binarnych ani wartości undefined.

Reguły składni JSON

JSON ma składnię, której należy ściśle przestrzegać. Nawet jeden błędny znak może spowodować niepowodzenie parsowania całego dokumentu. Zrozumienie tych zasad zapobiega najczęstszym błędom formatowania.

Ciągi muszą używać podwójnych cudzysłowów

Wszystkie wartości ciągów i klucze obiektów muszą być ujęte w podwójne cudzysłowy. Pojedyncze cudzysłowy nie są prawidłowymi separatorami ciągów JSON. Jest to jeden z najczęstszych błędów popełnianych przez deweloperów przechodzących z JavaScript, gdzie pojedyncze i podwójne cudzysłowy są wymienne.

// Invalid - single quotes
{'name': 'Alice', 'age': 30}

// Valid - double quotes
{"name": "Alice", "age": 30}

Klucze obiektów muszą być w cudzysłowach

W przeciwieństwie do literałów obiektów JavaScript, JSON wymaga, aby wszystkie klucze obiektów były ujęte w podwójne cudzysłowy. Niezacytowane klucze są błędem składniowym.

// Invalid - unquoted keys
{name: "Alice", age: 30}

// Valid - quoted keys
{"name": "Alice", "age": 30}

Zakaz końcowych przecinków

JSON nie zezwala na przecinek po ostatnim elemencie obiektu lub tablicy. To kolejny częsty błąd programistów JavaScript, gdzie przecinek końcowy jest dozwolony (a w niektórych przewodnikach stylu nawet zalecany).

// Invalid - trailing comma
{
  "name": "Alice",
  "age": 30,
}

// Valid - no trailing comma
{
  "name": "Alice",
  "age": 30
}

Komentarze nieobsługiwane

JSON nie obsługuje komentarzy. // komentarze jednoliniowe i /* */ komentarze wieloliniowe są nieprawidłowe w JSON. Jeśli potrzebujesz dołączyć dokumentację, rozważ użycie osobnego pliku dokumentacji lub formatu JSONC (JSON z komentarzami) obsługiwanego przez niektóre narzędzia.

Ścisłe typy wartości

Wartości JSON muszą być jednym z sześciu obsługiwanych typów. undefined, NaN, Infinity i -Infinity nie są prawidłowymi wartościami JSON. Zawarcie którejkolwiek z nich spowoduje błąd parsowania lub wygeneruje niestandardowy JSON, który wiele parserów odrzuci.

Typowe błędy formatowania

Oprócz błędów składniowych istnieje kilka błędów formatowania, które tworzą technicznie poprawny, ale problematyczny JSON:

Pretty-print a kompresja

Dwa główne tryby formatowania JSON służą różnym celom i ważne jest, aby używać właściwego formatu w odpowiednim kontekście.

JSON sformatowany

Formatowanie dodaje wcięcia i znaki nowej linii, aby JSON był czytelny dla człowieka. Jest to niezbędne podczas rozwoju, debugowania i pisania dokumentacji. Większość formaterów JSON domyślnie używa wcięcia 2 spacji:

{
  "users": [
    {
      "id": 1,
      "name": "Alice",
      "email": "alice@example.com"
    },
    {
      "id": 2,
      "name": "Bob",
      "email": "bob@example.com"
    }
  ]
}

JSON skompresowany

Kompresja usuwa wszystkie niepotrzebne białe znaki, tworząc najmniejszy możliwy prawidłowy JSON. Jest to kluczowe dla produkcyjnych API, gdzie każdy bajt ma znaczenie:

{"users":[{"id":1,"name":"Alice","email":"alice@example.com"},{"id":2,"name":"Bob","email":"bob@example.com"}]}

Kiedy używać którego

KontekstFormatPrzyczyna
Rozwój i debugowaniePretty-printCzytelność i szybkie skanowanie
Pliki konfiguracyjnePretty-printLudzie muszą czytać i edytować te pliki
Odpowiedzi produkcyjnego APIKompresujMniejsze ładunki, szybsza transmisja
Pliki dziennikaKompresja (jeden obiekt na linię)Kompaktowe przechowywanie, łatwe do przeszukiwania grep
Kontrola wersjiPretty-printZnaczące różnice i mniej konfliktów scalania
Najlepsza praktyka: zawsze przechowuj JSON w formacie sformatowanym w kontroli wersji. Używaj kompresji jako kroku budowania przed wdrożeniem. W ten sposób uzyskujesz czytelne porównania różnic, jednocześnie czerpiąc korzyści wydajnościowe skompresowanego JSON w środowisku produkcyjnym.

Walidacja JSON Schema

Chociaż walidacja składni JSON sprawdza, czy dokument jest poprawnie sformatowany, nie weryfikuje, czy dane mają oczekiwaną strukturę, typy lub wartości. JSON Schema wypełnia tę lukę, dostarczając słownictwo do opisywania oczekiwanego kształtu danych JSON.

Czym jest JSON Schema?

JSON Schema to dokument JSON opisujący strukturę innych dokumentów JSON. Pozwala określać wymagane pola, oczekiwane typy, zakresy wartości, wzorce stringów i struktury zagnieżdżonych obiektów. Dokument JSON zgodny ze Schema nazywany jest prawidłową instancją.

Typowe funkcje schematu

Kiedy używać walidacji schematu

Powinieneś używać walidacji JSON Schema za każdym razem, gdy otrzymujesz JSON z zewnętrznych źródeł: treści żądań API, pliki konfiguracyjne, importy danych i ładunki kolejek wiadomości. Walidacja schematu wyłapuje błędy wcześnie, dostarcza jasne komunikaty o błędach i służy jako żywa dokumentacja formatu danych. Biblioteki takie jak Ajv (JavaScript), jsonschema (Python) i json-schema-validator (Java) ułatwiają integrację walidacji schematu z dowolną aplikacją.

Wpływ rozmiaru JSON na wydajność

Rozmiar dokumentu JSON bezpośrednio wpływa na wydajność aplikacji w wielu aspektach: czas transmisji sieciowej, czas parsowania i zużycie pamięci. Zrozumienie tych wpływów pomaga podejmować świadome decyzje dotyczące formatowania i struktury JSON.

Transmisja sieciowa

Każdy bajt JSON musi być przesłany przez sieć z serwera do klienta. Na szybkich połączeniach różnica między 10KB a 100KB może wydawać się nieznaczna, ale dla użytkowników w sieciach komórkowych lub regionach o wolniejszym Internecie wpływ jest znaczący. Badania pokazują, że każde dodatkowe 100ms czasu ładowania zmniejsza współczynnik konwersji o około 1%. Kompresja zazwyczaj zmniejsza rozmiar JSON o 30-50%, a kompresja gzip dodatkowo o 70-85%. Zawsze włączaj kompresję gzip lub Brotli dla odpowiedzi JSON API.

Wydajność parsowania

Koszt parsowania JSON jest zaskakująco wysoki. W przypadku dużych dokumentów (powyżej 1MB) parsowanie na urządzeniach mobilnych może zająć setki milisekund. Koszt jest w przybliżeniu liniowy względem rozmiaru dokumentu. Kluczowe strategie redukcji kosztów parsowania obejmują: wysyłanie tylko danych potrzebnych klientowi (filtrowanie pól), stronicowanie dużych zestawów wyników oraz używanie bardziej wydajnych formatów serializacji, takich jak Protocol Buffers lub MessagePack, do komunikacji między usługami wewnętrznymi, gdzie czytelność dla człowieka nie jest potrzebna.

Zużycie pamięci

Sparsowany JSON zazwyczaj zużywa 3-10 razy więcej pamięci niż jego forma zserializowana, ponieważ każda wartość staje się oddzielnym obiektem z własną alokacją pamięci. Ciąg JSON o rozmiarze 1MB może używać 5-10MB RAM po sparsowaniu. Dla aplikacji JavaScript działających w przeglądarkach z ograniczoną pamięcią może to prowadzić do degradacji wydajności lub awarii na urządzeniach z niższej półki.

JSON a JSONL

JSON Lines (JSONL lub NDJSON) to pokrewny format, który rozwiązuje kluczowe ograniczenie JSON: wymóg parsowania całego dokumentu jako pojedynczej jednostki. W JSONL każda linia pliku jest kompletnym, niezależnym obiektem JSON.

Kiedy używać JSONL

Kiedy trzymać się standardowego JSON

Obsługa dużych plików JSON

Duże pliki JSON (powyżej 10MB) stanowią unikalne wyzwania wymagające specjalnego traktowania. Standardowe metody parsowania mogą zawodzić lub działać słabo przy tej skali.

Parsery strumieniowe

Parsery strumieniowe (lub w stylu SAX) przetwarzają JSON przyrostowo, bez ładowania całego dokumentu do pamięci. Emitują zdarzenia, gdy napotykają elementy strukturalne, takie jak początek obiektu, pary klucz-wartość i elementy tablicy. To podejście używa stałej pamięci niezależnie od rozmiaru pliku. Biblioteki takie jak oboe.js (JavaScript), ijson (Python) i Jackson Streaming API (Java) zapewniają strumieniowe parsowanie JSON.

Praktyczne wskazówki dla dużych plików

Zagadnienia bezpieczeństwa JSON

Chociaż JSON jest formatem danych i sam w sobie nie jest niebezpieczny, sposób, w jaki aplikacje przetwarzają JSON, może wprowadzać luki. Zrozumienie tych zagrożeń jest niezbędne do budowania bezpiecznych systemów.

Nigdy nie używaj eval() do parsowania JSON

Najważniejsza zasada bezpieczeństwa: nigdy nie używaj funkcji eval() JavaScript do parsowania JSON. eval() wykonuje dowolny kod JavaScript, co oznacza, że złośliwy ładunek JSON może uruchomić kod na komputerze użytkownika. Zawsze używaj JSON.parse(), który parsuje tylko prawidłowy JSON i odrzuca wszelki kod wykonywalny. To nie podlega dyskusji.

JSONP i ryzyko cross-origin

JSONP (JSON z paddingiem) to technika omijania ograniczeń polityki samego pochodzenia, zanim CORS został szeroko wsparty. Działa poprzez opakowanie danych JSON w wywołanie funkcji, które jest wykonywane jako skrypt. Jest to z natury niebezpieczne, ponieważ wykonuje dowolny JavaScript z serwera strony trzeciej. Jeśli kontrolujesz zarówno klienta, jak i serwer, użyj CORS zamiast JSONP. JSONP powinien być uważany za technologię przestarzałą i należy go unikać w nowych aplikacjach.

Zanieczyszczenie prototypu

Podczas scalania lub głębokiego kopiowania obiektów JSON w JavaScript, uważaj na klucze takie jak __proto__, constructor i prototype. Jeśli JSON dostarczony przez użytkownika jest rekurencyjnie scalany z istniejącymi obiektami bez oczyszczania tych kluczy, może zmodyfikować prototyp wszystkich obiektów w aplikacji, prowadząc do eskalacji uprawnień lub odmowy usługi. Zawsze oczyszczaj klucze obiektów przed scalaniem.

Odmowa usługi przez głębokie zagnieżdżenie

Starannie spreparowane dokumenty JSON o ekstremalnej głębokości zagnieżdżenia (tysiące poziomów) mogą powodować błędy przepełnienia stosu w parserach rekurencyjnych. Złagodź to, ustawiając maksymalną głębokość zagnieżdżenia w parserze. Większość produkcyjnych parserów JSON pozwala skonfigurować to ograniczenie.

Walidacja danych wejściowych

Nigdy nie ufaj danym JSON z zewnętrznych źródeł. Zawsze waliduj strukturę, typy i zakresy wartości przychodzącego JSON przed użyciem. Walidacja JSON Schema jest najbardziej niezawodną metodą, ale nawet proste sprawdzenia wymaganych pól i asercji typów zapewniają znaczącą ochronę przed zniekształconymi lub złośliwymi danymi wejściowymi.

Potrzebujesz sformatować, zweryfikować lub skompresować JSON? Wypróbuj nasze darmowe narzędzia JSON online. Całe przetwarzanie odbywa się w twojej przeglądarce, zapewniając maksymalną szybkość i prywatność.

Narzędzia do formatowania JSONWalidator JSON

FAQ

Jaka jest różnica między sformatowanym a skompresowanym JSON?

Sformatowany JSON zawiera białe znaki (wcięcia, znaki nowej linii) do czytania przez człowieka, podczas gdy skompresowany JSON usuwa wszystkie niepotrzebne białe znaki, aby zminimalizować rozmiar pliku. Używaj sformatowanego JSON podczas rozwoju i debugowania, a skompresowanego JSON w środowisku produkcyjnym dla mniejszych ładunków sieciowych i szybszego parsowania.

Jakie są najczęstsze błędy formatowania JSON?

Najczęstsze błędy to: końcowe przecinki po ostatnim elemencie obiektu lub tablicy, używanie pojedynczych cudzysłowów zamiast podwójnych dla ciągów, dodawanie komentarzy (JSON nie obsługuje komentarzy), używanie niezacytowanych kluczy obiektów oraz zawieranie wartości, które nie są prawidłowym JSON, takich jak undefined lub NaN.

Kiedy powinienem używać JSONL zamiast JSON?

Używaj JSONL (JSON Lines), gdy potrzebujesz przyrostowo przetwarzać rekordy, na przykład w przypadku plików dziennika, strumieni danych lub dużych zbiorów danych, które nie mieszczą się w pamięci. Każda linia jest kompletnym obiektem JSON, więc możesz czytać i parsować po jednej linii bez ładowania całego pliku. Standardowy JSON wymaga sparsowania całego dokumentu przed dostępem do jakichkolwiek danych.

Jak walidować JSON według schematu?

Użyj JSON Schema do zdefiniowania oczekiwanej struktury danych JSON, a następnie użyj bibliotek takich jak Ajv (JavaScript), jsonschema (Python) lub walidatora online do walidacji instancji według tego schematu. JSON Schema pozwala określić wymagane pola, typy, zakresy wartości, wzorce ciągów i struktury zagnieżdżonych obiektów.

Czy JSON jest bezpieczny do wymiany danych?

JSON sam w sobie jest formatem danych, który nie jest ani bezpieczny, ani niebezpieczny. Jednak sposób, w jaki analizujesz i używasz JSON, może wprowadzać luki. Głównym ryzykiem jest używanie eval() do parsowania JSON (nigdy tego nie rób — zawsze używaj JSON.parse()). Ponadto uważaj na JSONP, który może omijać politykę samego pochodzenia. Zawsze waliduj i oczyszczaj dane JSON z niezaufanych źródeł przed użyciem.