Mam trudności z analizowaniem niektórych danych JSON zwróconych z mojego serwera za pomocą jQuery.ajax ()
Aby wykonać AJAX, którego używam:
$.ajax({
url: myUrl,
cache: false,
dataType: "json",
success: function(data){
...
},
error: function(e, xhr){
...
}
});
A jeśli zwrócę tablicę elementów, to działa dobrze:
[ { title: "One", key: "1" }, { title: "Two", key: "2" } ]
Funkcja sukcesu jest wywoływana i otrzymuje prawidłowy obiekt.
Jednak gdy próbuję zwrócić pojedynczy obiekt:
{ title: "One", key: "1" }
Wywoływana jest funkcja błędu, a xhr zawiera „parsererror”. Próbowałem zawinąć JSON w nawias na serwerze przed wysłaniem go dalej, ale to nie robi różnicy. Jednak jeśli wkleię zawartość do ciągu znaków w JavaScript, a następnie użyję funkcji eval (), oceni ją doskonale.
Jakieś pomysły, co robię źle?
Anthony
Odpowiedzi:
Czy Twój serwer wysyła dane jako typ zawartości
"*/json"
? Jeśli nie, odpowiednio zmodyfikuj nagłówki odpowiedzi. Na przykład wysyłanie"application/json"
byłoby w porządku.źródło
Zgodnie ze specyfikacją json.org Twój zwrot jest nieprawidłowy. Imiona są zawsze cytowane, więc powinieneś wracać
{ "title": "One", "key": "1" }
i
[ { "title": "One", "key": "1" }, { "title": "Two", "key": "2" } ]
Może to nie być problem z twoją konfiguracją, ponieważ mówisz, że jeden z nich działa teraz, ale powinien zostać naprawiony pod kątem poprawności na wypadek konieczności przełączenia się na inny parser JSON w przyszłości.
źródło
{ key: 'val' }
nie jest poprawnym JSON.Ciągi JSON są zawijane w podwójne cudzysłowy; apostrofy nie są prawidłowym zamiennikiem.
{"who": "Hello World"}
jest ważne, ale to nie jest ...
{'who': 'Hello World'}
Chociaż nie jest to kwestia PO, pomyśleliśmy, że warto zwrócić uwagę na innych, którzy tu lądują.
źródło
Ten problem jest zwykle spowodowany tym, że żądanie otrzymało niewłaściwy typ MIME. Podczas programowania na własnym komputerze, czasami nie otrzymujesz odpowiedniego typu MIME z „serwera”, którym jest Twój własny komputer. Kiedyś napotkałem ten problem podczas programowania, otwierając lokalnie przechowywany plik w przeglądarce (np. Adres URL to „c: /project/test.html”).
Spróbuj użyć właściwości beforeSend, aby dodać funkcję zwrotną, która zastępuje typ MIME. Spowoduje to, że kod poradzi sobie z json pomimo wysłania przez serwer niewłaściwego typu MIME i odebrania go przez kod wywołujący. Poniżej znajduje się przykładowy kod.
Odpowiedni typ mime to application / json zgodnie z tym pytaniem , ale wiem, że application / j-son działał, kiedy go wypróbowałem (teraz kilka lat temu). Prawdopodobnie powinieneś najpierw wypróbować application / json.
var jsonMimeType = "application/json;charset=UTF-8"; $.ajax({ type: "GET", url: myURL, beforeSend: function(x) { if(x && x.overrideMimeType) { x.overrideMimeType(jsonMimeType); } }, dataType: "json", success: function(data){ // do stuff... } });
źródło
Miałem ten problem i przez jakiś czas korzystałem
eval('('+data+')')
aby uzyskać dane zwrócone w obiekcie. ale później wystąpiły inne problemy z błędem `` brakujący) w nawiasach i okazało się, że jQuery ma funkcję przeznaczoną specjalnie do oceny ciągu dla struktury json:
$.parseJSON(data)
powinien załatwić sprawę. Jest to oczywiście dodatek do posiadania łańcucha json w odpowiednim formacie.
źródło
Jeśli odbierasz odpowiedź json, a nagłówki nie są zgodne * / json, możesz użyć wbudowanego interfejsu API jQuery.parseJSON do przeanalizowania odpowiedzi.
response = '{"name":"John"}'; var obj = jQuery.parseJSON(response); alert( obj.name === "John" );
źródło
{ title: "One", key: "1" }
Nie jest tym, co myślisz. Jako wyrażenie jest to literał Object, ale jako instrukcja jest to:
{ // new block title: // define a label called 'title' for goto statements "One", // statement: the start of an expression which will be ignored key: // ...er, what? you can't have a goto label in the middle of an expression // ERROR
Niestety eval () nie daje możliwości określenia, czy podajesz instrukcję, czy wyrażenie, i ma tendencję do błędnego odgadywania.
Zwykłym rozwiązaniem jest rzeczywiście zawijanie czegokolwiek w nawiasach przed wysłaniem tego do funkcji eval (). Mówisz, że próbowałeś tego na serwerze ... najwyraźniej jakoś to się nie udaje. Powinien być wodoodporny, aby powiedzieć po stronie klienta, cokolwiek otrzymuje odpowiedź XMLHttpRequest:
eval('('+responseText+')');
zamiast:
eval(responseText);
o ile odpowiedź jest rzeczywiście wyrażeniem, a nie stwierdzeniem. (np. nie zawiera wielu klauzul oddzielonych średnikiem lub znakiem nowej linii).
źródło
Będziesz musiał ustawić typ zawartości nagłówka w swoim php w następujący sposób:
<?php header('Content-type:application/json'); ?>
Obejrzyj ten film, aby lepiej zrozumieć ...
Źródła: http://www.youtube.com/watch?v=EvFXWqEqh6o
źródło
Jeśli korzystasz z usług sieci Web ASP.NET przy użyciu jQuery, upewnij się, że plik web.config zawiera następujące elementy:
<webServices> <protocols> <add name="HttpGet"/> <add name="HttpPost"/> </protocols> </webServices>
źródło
Miałem podobny problem do tego, w którym Firefox 3.5 działał dobrze i przeanalizował moje dane JSON, ale Firefox 3.0.6 zwrócił parseerror. Okazało się, że to puste miejsce na początku JSON spowodowało, że Firefox 3.0.6 wyrzucił błąd. Usunięcie pustej przestrzeni naprawiło to
źródło
Techniki „eval ()” i „JSON.parse ()” wykorzystują wzajemnie wykluczające się formaty.
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... } // this looks like a compound statement
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" } ) // not a compound statment, so must be object literal
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:
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ę wres.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'); // generates eval() format
Może to być przydatne, ale jeśli nie masz konkretnej potrzeby, prawdopodobnie nie jest to to, czego chcesz.
źródło
Jeśli zwrócenie tablicy działa, a zwrócenie pojedynczego obiektu nie, możesz również spróbować zwrócić pojedynczy obiekt jako tablicę zawierającą ten pojedynczy obiekt:
[ { title: "One", key: "1" } ]
w ten sposób zwracasz spójną strukturę danych, tablicę obiektów, bez względu na ładunek danych.
Widzę, że próbowałeś opakować swój pojedynczy obiekt w nawias i sugeruję to na przykładzie, ponieważ oczywiście JavaScript traktuje [..] inaczej niż (..)
źródło
Jeśli wywoływana jest procedura obsługi błędów jQuery, a obiekt XHR zawiera „błąd parsera”, prawdopodobnie jest to błąd parsera wracający z serwera.
Czy Twój scenariusz z wieloma wynikami wywołuje usługę bez parametru, ale przerywa się, gdy próbujesz podać parametr w celu pobrania pojedynczego rekordu?
Z jakiego zaplecza zwracasz to?
Na przykład w usługach ASMX dzieje się tak często, gdy parametry są dostarczane do jQuery jako obiekt JSON zamiast ciągu JSON. Jeśli podasz jQuery rzeczywisty obiekt JSON dla jego parametru „data”, zostanie on serializowany do standardowych i rozdzielanych par k, v zamiast wysyłać go jako JSON.
źródło
W niektórych swoich wdrożeniach znalazłem:
obj = new Object; obj = (data.obj);
co wydawało się rozwiązać problem. Eval czy nie, wydawało mi się, że robi dokładnie to samo dla mnie.
źródło
jQuery dławi się na niektórych kluczach JSON. Wysyłałem ten fragment kodu JSON w PHP:
echo json_encode((object) array('result' => 'success'));
Zmiana nazwy klucza „wynik” na coś innego działa. Wydaje mi się, że jest to jakiś rodzaj kolizji słów zastrzeżonych i może to być błąd w jQuery (1.4.2).
źródło
W środowisku ColdFusion jedyną rzeczą, która spowoduje błąd, nawet przy poprawnie sformułowanym formacie JSON, jest włączenie opcji Włącz żądanie debugowania w module Administrator ColdFusion (w sekcji Debugowanie i rejestrowanie> Ustawienia wyjścia debugowania). Informacje debugowania zostaną zwrócone wraz z danymi JSON, co spowoduje, że będą nieprawidłowe.
źródło
też spróbuj tego
$.ajax({ url: url, data:datas, success:function(datas, textStatus, jqXHR){ var returnedData = jQuery.parseJSON(datas.substr(datas.indexOf('{'))); })};
w moim przypadku serwer odpowiada nieznanym znakiem przed '{'
źródło
Otrzymywałem status = parseerror i xhr.status = 200.
Problem polegał na tym, że adres URL w odpowiedzi JSON miał '\' przełączenie na '/' naprawione.
źródło
Walczyłem z tym i spędziłem kilka godzin próbując to rozgryźć, aż użyłem firebuga do pokazania obiektu danych.
var data = eval("(" + data.responseText + ")"); console.log(data.count);
źródło
posługiwać się
$data = yourarray(); json_encode($data)
po stronie serwera. Po stronie klienta użyj ajax z typem danych JSON i upewnij się, że kodowanie twojego dokumentu nie jest UTF-8 z BOM, musi to być UTF-8.
źródło