Uncaught SyntaxError: Nieoczekiwany token z JSON.parse

192

co powoduje ten błąd w trzeciej linii?

var products = [{
  "name": "Pizza",
  "price": "10",
  "quantity": "7"
}, {
  "name": "Cerveja",
  "price": "12",
  "quantity": "5"
}, {
  "name": "Hamburguer",
  "price": "10",
  "quantity": "2"
}, {
  "name": "Fraldas",
  "price": "6",
  "quantity": "2"
}];
console.log(products);
var b = JSON.parse(products); //unexpected token o

Otwórz konsolę, aby wyświetlić błąd

coiso
źródło
16
Nie masz JSON? Jest to literał tablicowy / obiektowy.
Bergi,

Odpowiedzi:

220

productsjest przedmiotem. (tworzenie z dosłowności obiektu)

JSON.parse()służy do konwersji ciągu zawierającego notację JSON na obiekt JavaScript.

Twój kod zamienia obiekt w ciąg (przez wywołanie .toString()), aby spróbować go parsować jako tekst JSON.
Domyślnie .toString()zwraca wartość "[object Object]", która nie jest poprawna JSON; stąd błąd.

SLaks
źródło
1
czy to nie jest tablica? Dlaczego to jest przedmiot? Obiekty zaczynają się od {, a tablice zaczynają się od [? lub czy jestem fałszywy tutaj
4
Tablice są obiektami; to .toString()zwraca (zgodnie ze specyfikacją).
SLaks,
1
Czy rozwiązaniem jest najpierw skreślić obiekt?
Mohammed Noureldin
6
@MohammedNoureldin: Nie; rozwiązaniem jest nic nie robić i używać swojego obiektu.
SLaks
2
Co się stanie, jeśli otrzymam moje dane ze zdalnej usługi za pomocą Ajax, która zwróci mi odpowiedź Jsona? I chcę, aby ta odpowiedź została zapisana w obiekcie tablicy JavaScript?
Mohammed Noureldin
125

Powiedzmy, że wiesz, że to prawidłowy JSON, ale nadal otrzymujesz to ...

W takim przypadku prawdopodobne jest, że w ciągu znajdują się ukryte / znaki specjalne z dowolnego źródła. Gdy wkleisz do walidatora, zostaną one utracone - ale w łańcuchu wciąż tam są. Te znaki, choć niewidoczne, się złamiąJSON.parse()

Jeśli sjest to Twój surowy JSON, oczyść go za pomocą:

// preserve newlines, etc - use valid JSON
s = s.replace(/\\n/g, "\\n")  
               .replace(/\\'/g, "\\'")
               .replace(/\\"/g, '\\"')
               .replace(/\\&/g, "\\&")
               .replace(/\\r/g, "\\r")
               .replace(/\\t/g, "\\t")
               .replace(/\\b/g, "\\b")
               .replace(/\\f/g, "\\f");
// remove non-printable and other non-valid JSON chars
s = s.replace(/[\u0000-\u0019]+/g,""); 
var o = JSON.parse(s);
EdH
źródło
Wystąpił błąd i wyśledziłem go w dziwnej postaci w ciągu. Użyłem twojej metody usuwania niepoprawnych znaków JSON i zadziałało.
albertski,
1
przyjechałem tu już dwa razy. dzięki
Benjamin Hoffman,
Po dekodowaniu Base64 mam końcowy znak specjalny, twoja metoda bardzo mi pomogła! Dzięki
Guillaume,
nie ufaj źródłu odpowiadającemu niepoprawnym JSON. Po prostu poinformuj ich, że dane są uszkodzone. powinni to naprawić. jeśli spróbujesz „odzyskać” odpowiedź w ten sposób lub w podobny sposób, utrzymasz niestabilną komunikację.
Onur Yıldırım
Powinien być s = s.replace(/[\u0000-\u001F]+/g,""); zamiast s = s.replace(/[\u0000-\u0019]+/g,""); , do zamiany wszystkich znaków kontrolnych. Dobrze?
HongchaoZhang,
64

Wygląda na to, że chcesz skreślić obiekt. Więc zrób to:

JSON.stringify(products);

Przyczyną błędu jest to, że JSON.parse()oczekuje Stringwartości i productsjest to Array.

Uwaga: Myślę, że próby json.parse('[object Array]'), która narzeka, że nie spodziewałem tokena opo [.

Onur Yıldırım
źródło
28

Znalazłem ten sam problem z JSON.parse(inputString).

W moim przypadku ciąg wejściowy pochodzi z mojej strony serwera [powrót metody strony] .

Wydrukowałem typeof(inputString)- to był ciąg, wciąż występuje błąd.

Próbowałem też JSON.stringify(inputString), ale to nie pomogło.

Później stwierdziłem, że jest to problem z nowym operatorem linii [\n] wewnątrz wartości pola.

Zrobiłem zamianę [z inną postacią, wstawiłem nową linię po analizie] i wszystko działa dobrze.

Derin
źródło
2
Nowy znak linii był również moim problemem. Jak więc możemy przywrócić takie dane?
kolenda
@kolenda Masz nieprawidłowy JSON. Musisz zmienić serwer, aby używał faktycznego serializatora JSON, który zwraca prawidłowy JSON.
SLaks,
Miałem podobny problem, ale zamiast „\ n” miałem „\ e” wewnątrz ścieżki (zmieniłem kod po stronie serwera, aby używał „/” zamiast „\” i wszystko znowu działało)
Adam Tal
użyj ucieczki, w której \ n byłoby \\ n
Paul Gregoire,
14

JSON.parse czeka na parametr w parametrze String. Musisz rozwikłać swój obiekt JSON, aby rozwiązać problem.

products = [{"name":"Pizza","price":"10","quantity":"7"}, {"name":"Cerveja","price":"12","quantity":"5"}, {"name":"Hamburguer","price":"10","quantity":"2"}, {"name":"Fraldas","price":"6","quantity":"2"}];
console.log(products);
var b = JSON.parse(JSON.stringify(products));  //solves the problem
Térence
źródło
12
products = [{"name":"Pizza","price":"10","quantity":"7"}, {"name":"Cerveja","price":"12","quantity":"5"}, {"name":"Hamburguer","price":"10","quantity":"2"}, {"name":"Fraldas","price":"6","quantity":"2"}];

zmień na

products = '[{"name":"Pizza","price":"10","quantity":"7"}, {"name":"Cerveja","price":"12","quantity":"5"}, {"name":"Hamburguer","price":"10","quantity":"2"}, {"name":"Fraldas","price":"6","quantity":"2"}]';
pktangyue
źródło
2
@SLaks tak, OP może bezpośrednio używać produktów. ale jeśli chce użyć JSON.parse, argumenty muszą być ciągiem.
pktangyue
co powinienem zrobić w ASP Classic, ponieważ „jest komentarzem
ashish bhatt
1
@ashishbhatt można użyć ”, a następnie zmień wszystkie inne„ na \ ”
pktangyue
2
Coś w tym styluJSON.parse(products.replace(/'/g, '"'))
programista chemiczny
11

Należy sprawdzić poprawność ciąg JSON tutaj .

Prawidłowy ciąg JSON musi zawierać podwójne cudzysłowy wokół klawiszy:

JSON.parse({"u1":1000,"u2":1100})       // will be ok

Jeśli nie ma cytatów, spowoduje to błąd:

JSON.parse({u1:1000,u2:1100})    
// error Uncaught SyntaxError: Unexpected token u in JSON at position 2

Użycie pojedynczych cudzysłowów spowoduje również błąd:

JSON.parse({'u1':1000,'u2':1100})    
// error Uncaught SyntaxError: Unexpected token ' in JSON at position 1
hoogw
źródło
W moim przypadku Grails 2.5.6 renderowany render ([key: value])z pojedynczymi cudzysłowami, co prowadzi do analizy składni JSON na pozycji 1 w jQuery Ajax. render (groovy.json.JsonOutput.toJson ([key:value]))pomógł mi.
philburns,
3
[
  {
    "name": "Pizza",
    "price": "10",
    "quantity": "7"
  },
  {
    "name": "Cerveja",
    "price": "12",
    "quantity": "5"
  },
  {
    "name": "Hamburguer",
    "price": "10",
    "quantity": "2"
  },
  {
    "name": "Fraldas",
    "price": "6",
    "quantity": "2"
  }
]

Oto twój idealny Json, który możesz przeanalizować.

San
źródło
3

Oto funkcja, którą wykonałem na podstawie poprzednich odpowiedzi: działa na moim komputerze, ale YMMV.

          /**
             * @description Converts a string response to an array of objects.
             * @param {string} string - The string you want to convert.
             * @returns {array} - an array of objects.
            */
            function stringToJson(input) {
              var result = [];

              //replace leading and trailing [], if present
              input = input.replace(/^\[/,'');
              input = input.replace(/\]$/,'');

              //change the delimiter to 
              input = input.replace(/},{/g,'};;;{');

              // preserve newlines, etc - use valid JSON
              ///programming/14432165/uncaught-syntaxerror-unexpected-token-with-json-parse
            input = input.replace(/\\n/g, "\\n")  
            .replace(/\\'/g, "\\'")
            .replace(/\\"/g, '\\"')
            .replace(/\\&/g, "\\&")
            .replace(/\\r/g, "\\r")
            .replace(/\\t/g, "\\t")
            .replace(/\\b/g, "\\b")
            .replace(/\\f/g, "\\f");
            // remove non-printable and other non-valid JSON chars
            input = input.replace(/[\u0000-\u0019]+/g,""); 

              input = input.split(';;;');

              input.forEach(function(element) {
                // console.log(JSON.stringify(element));

                result.push(JSON.parse(element));
              }, this);

              return result;
            }
tmurphree
źródło
2

Inny gotcha, który może powodować "SyntaxError: Unexpected token"wyjątek podczas wywoływania, JSON.parse()używa jednej z następujących wartości ciągu:

  1. Znaki nowej linii.

  2. Karty (tak, karty, które można tworzyć za pomocą klawisza Tab!)

  3. Wszelkie samodzielne ukośniki \(ale z jakiegoś powodu nie /, przynajmniej nie w Chrome).

(Aby uzyskać pełną listę, zobacz sekcję String tutaj .)

Na przykład następujący wyjątek zapewni ci ten wyjątek:

{
    "msg" : {
        "message": "It cannot
contain a new-line",
        "description": "Some discription with a     tabbed space is also bad",
        "value": "It cannot have 3\4 un-escaped"
    }
}

Dlatego należy zmienić na:

{
    "msg" : {
        "message": "It cannot\ncontain a new-line",
        "description": "Some discription with a\t\ttabbed space",
        "value": "It cannot have 3\\4 un-escaped"
    }
}

Co, należy powiedzieć, sprawia, że ​​jest dość nieczytelny w formacie tylko JSON z większą ilością tekstu.

c00000fd
źródło
1

Mam nadzieję, że pomoże to komuś innemu.

Mój problem polegał na tym, że skomentowałem HTML w funkcji wywołania zwrotnego PHP za pośrednictwem AJAX, która analizowała komentarze i zwróciła niepoprawny JSON.

Po usunięciu skomentowanego kodu HTML wszystko było w porządku, a JSON został przeanalizowany bez żadnych problemów.

Chris
źródło
0

produkty to tablica, z której można korzystać bezpośrednio:

var i, j;

for(i=0;i<products.length;i++)
  for(j in products[i])
    console.log("property name: " + j,"value: "+products[i][j]);
ic3b3rg
źródło
0

Teraz najwyraźniej \r, \b, \t,\f , itp nie są problemem tylko znaków, które mogą dać ci ten błąd.

Pamiętaj, że niektóre przeglądarki mogą mieć dodatkowe wymagania dotyczące wprowadzaniaJSON.parse .

Uruchom ten kod testowy w przeglądarce:

var arr = [];
for(var x=0; x < 0xffff; ++x){
    try{
        JSON.parse(String.fromCharCode(0x22, x, 0x22));
    }catch(e){
        arr.push(x);
    }
}
console.log(arr);

Testując na Chrome, widzę, że nie pozwala JSON.parse(String.fromCharCode(0x22, x, 0x22));gdziex jest 34, 92 lub od 0 do 31.

Znaki 34 i 92 to "i\ znaki odpowiednio, i są one zwykle oczekuje i właściwie uciekł. To znaki od 0 do 31, które sprawiłyby ci problemy.

Aby pomóc w debugowaniu, zanim to zrobisz JSON.parse(input), najpierw sprawdź, czy dane wejściowe nie zawierają problematycznych znaków:

function VerifyInput(input){
    for(var x=0; x<input.length; ++x){
        let c = input.charCodeAt(x);
        if(c >= 0 && c <= 31){
            throw 'problematic character found at position ' + x;
        }
    }
}
Pacerier
źródło
0

Dlaczego potrzebujesz JSON.parse? Jest już w tablicy formatu obiektowego.

Lepiej użyj JSON.stringify jak poniżej: var b = JSON.stringify(products);

To może ci pomóc.

abhijit padhy
źródło
0

O rany, wszystkie powyższe odpowiedzi nie były dla mnie skuteczne. Właśnie miałem podobny problem. Udało mi się to rozwiązać, pakując cytat. Zobacz zrzut ekranu. Whoo.

wprowadź opis zdjęcia tutaj

Oryginalny:

var products = [{
  "name": "Pizza",
  "price": "10",
  "quantity": "7"
}, {
  "name": "Cerveja",
  "price": "12",
  "quantity": "5"
}, {
  "name": "Hamburguer",
  "price": "10",
  "quantity": "2"
}, {
  "name": "Fraldas",
  "price": "6",
  "quantity": "2"
}];
console.log(products);
var b = JSON.parse(products); //unexpected token o

Cóż, Smith
źródło
0

Występujący błąd, tj. „Nieoczekiwany token o”, jest spowodowany oczekiwaniem JSON, ale obiekt jest uzyskiwany podczas analizowania. To „o” jest pierwszą literą słowa „przedmiot”.

Shashank Bodkhe
źródło
0

Jedynym błędem, który popełniasz, jest parsowanie już przeanalizowanego obiektu, więc generuje błąd, użyj go i będziesz gotowy.

var products = [{
  "name": "Pizza",
  "price": "10",
  "quantity": "7"
}, {
  "name": "Cerveja",
  "price": "12",
  "quantity": "5"
}, {
  "name": "Hamburguer",
  "price": "10",
  "quantity": "2"
}, {
  "name": "Fraldas",
  "price": "6",
  "quantity": "2"
}];
console.log(products[0].name); //name of item at 0th index

jeśli chcesz wydrukować cały Json, użyj JSON.stringify ()

Kiran Maniya
źródło
0

Może się to zdarzyć z wielu powodów, ale prawdopodobnie z powodu niepoprawnego znaku, więc możesz użyć JSON.stringify(obj);, który zmieni obiekt w JSON, ale pamiętaj, że jest to wyrażenie JQUERY.

Elvis Silva Noleto
źródło
0

Mam ten błąd, PONIEWAŻ API, które zwróciło obiekt json, dawało BŁĄD (w moim przypadku Code Igniter, zwraca html, gdy kod php zawiedzie), więc NIE JEST JSON OBJECT.

Sprawdź zdania SQL i kod PHP i przetestuj go za pomocą Postmana (lub innego testera API)

Ari Waisberg
źródło
0

Błąd, który popełniłem, był mijający null (nieświadomie) do JSON.parse ().

Więc rzucił Unexpected token n in JSON at position 0

Aashutosh Rathi
źródło
-24

Zastosowanie eval. Pobiera wyrażenie / kod JavaScript jako ciąg znaków i ocenia je / wykonuje.

eval(inputString);
Kasthuri
źródło
Każde wywołanie eval () tworzy nowe wystąpienie interpretera JavaScript. Może to być świnia zasobów.
Yëco