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.