Techniki „eval ()” i „JSON.parse ()” wykorzystują wzajemnie wykluczające się formaty.
- Z nawiasami „eval ()” są wymagane .
- W nawiasach „JSON.parse ()” nie wolno używać nawiasów .
Uwaga, istnieją funkcje „stringify ()”, które generują format „eval”. W przypadku AJAX należy używać tylko formatu JSON.
Podczas gdy „eval” obejmuje cały język JavaScript, JSON wykorzystuje tylko niewielki podzbiór języka. Wśród konstrukcji w języku JavaScript, które „eval” musi rozpoznać, jest „Instrukcja blokowa” (inaczej „instrukcja złożona”) ; który jest parą lub nawiasami klamrowymi „{}” z pewnymi instrukcjami w środku. Ale nawiasy klamrowe są również używane w składni literałów obiektowych. Interpretację różnicuje kontekst, w którym pojawia się kod. Coś może wyglądać jak obiekt dosłowny, ale „eval” zobaczy to jako instrukcję złożoną.
W języku JavaScript literały obiektowe pojawiają się po prawej stronie przypisania.
var myObj = { ...some..code..here... };
Literały obiektów nie występują samodzielnie.
{ ...some..code..here... }
Wracając do pierwotnego pytania OP, zadanego w 2008 r., Zapytał, dlaczego w „eval ()” nie powiodło się następujące pytanie:
{ title: "One", key: "1" }
Odpowiedź brzmi, że wygląda to jak instrukcja złożona. Aby przekształcić go w obiekt, należy umieścić go w kontekście, w którym instrukcja złożona jest niemożliwa. Odbywa się to poprzez umieszczenie wokół niego nawiasów
( { title: "One", key: "1" } )
PO zwróciła się także dlaczego podobna wypowiedź zrobiła powodzeniem eval:
[ { title: "One", key: "1" }, { title: "Two", key: "2" } ]
Ta sama odpowiedź ma zastosowanie - nawiasy klamrowe znajdują się w kontekście, w którym instrukcja złożona jest niemożliwa. To jest kontekst tablicy, " [...]
", a tablice mogą zawierać obiekty, ale nie mogą zawierać instrukcji.
W przeciwieństwie do „eval ()”, JSON ma bardzo ograniczone możliwości. Ograniczenie jest zamierzone. Projektant JSON miał na myśli minimalistyczny podzbiór JavaScript, używając tylko składni, która może pojawić się po prawej stronie zadania. Więc jeśli masz kod, który poprawnie analizuje w JSON ...
var myVar = JSON.parse("...some...code...here...");
... co oznacza, że zgodnie z prawem przeanalizuje również prawą stronę zadania, w ten sposób ...
var myVar = ...some..code..here... ;
Ale to nie jedyne ograniczenie JSON. Specyfikacja języka BNF dla JSON jest bardzo prosta. Na przykład nie pozwala na użycie pojedynczych cudzysłowów do wskazania łańcuchów (jak JavaScript i Perl) i nie ma sposobu na wyrażenie pojedynczego znaku jako bajtu (jak robi to „C”). Niestety nie pozwala również na komentarze (co byłoby bardzo fajne przy tworzeniu plików konfiguracyjnych). Zaletą wszystkich tych ograniczeń jest to, że analizowanie JSON jest szybkie i nie daje możliwości wstrzyknięcia kodu (zagrożenie bezpieczeństwa).
Z powodu tych ograniczeń JSON nie ma zastosowania w nawiasach. W rezultacie nawias w ciągu JSON jest niedozwolonym znakiem.
Zawsze używaj formatu JSON z ajaxem, z następujących powodów:
- Typowy potok ajax zostanie skonfigurowany dla JSON.
- Użycie metody „eval ()” będzie krytykowane jako zagrożenie bezpieczeństwa.
Jako przykład potoku Ajax rozważmy program, który obejmuje serwer Node i klienta jQuery. Program klienta używa wywołania jQuery o postaci $.ajax({dataType:'json',...etc.});
. JQuery tworzy obiekt jqXHR do późniejszego użycia, a następnie pakuje i wysyła powiązane żądanie. Serwer przyjmuje żądanie, przetwarza je i jest gotowy do odpowiedzi. Program serwera wywoła metodę w res.json(data)
celu spakowania i wyśle odpowiedź. Po stronie klienta jQuery akceptuje odpowiedź, konsultuje się z powiązanym obiektem jqXHR i przetwarza dane w formacie JSON. To wszystko działa bez konieczności ręcznej konwersji danych. Odpowiedź nie zawiera jawnego wywołania JSON.stringify () na serwerze Node ani jawnego wywołania JSON.parse () na kliencie; to wszystko załatwiamy za Ciebie.
Użycie „eval” wiąże się z zagrożeniami bezpieczeństwa polegającymi na wstrzykiwaniu kodu. Możesz pomyśleć, że nie ma takiej możliwości, ale hakerzy mogą być całkiem kreatywni. Również „eval” jest problematyczne dla optymalizacji Javascript.
Jeśli zauważysz, że korzystasz z funkcji „stringify ()”, pamiętaj, że niektóre funkcje o tej nazwie utworzą ciągi zgodne z „eval”, a nie z JSON. Na przykład, w Node, poniżej przedstawiono funkcję, która tworzy ciągi znaków w formacie zgodnym z „eval”:
var stringify = require('node-stringify');
Może to być przydatne, ale jeśli nie masz konkretnej potrzeby, prawdopodobnie nie jest to to, czego chcesz.