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


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.


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);

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 [.


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.


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

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"}]';

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

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ć.


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;
            }

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.



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.


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]);

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;
        }
    }
}

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.


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


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”.


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 ()


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.


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)


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


-24

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

eval(inputString);

Każde wywołanie eval () tworzy nowe wystąpienie interpretera JavaScript. Może to być świnia zasobów.
Yëco
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.