SyntaxError não capturado: token inesperado com JSON.parse


190

o que causa esse erro na terceira linha?

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

Abra o console para visualizar o erro


16
Você não tem nenhum JSON? É um literal de matriz / objeto.
— Bergi

Respostas:


219

productsé um objeto. (criando a partir de um literal de objeto)

JSON.parse()é usado para converter uma string contém a notação JSON em um objeto Javascript.

Seu código transforma o objeto em uma string (chamando .toString()) para tentar analisá-lo como texto JSON.
O padrão .toString()retorna "[object Object]", que não é JSON válido; daí o erro.


1
não é uma matriz? Por que isso é um objeto? Os objetos começam com {e as matrizes começam com [? ou sou falso aqui

4
Matrizes são objetos; é isso que .toString()retorna (conforme as especificações).
— SLaks 04/09/16

1
A solução para restringir o objeto primeiro?
— Mohammed Noureldin 3/02

6
@MohammedNoureldin: Não; a solução é não fazer nada e usar seu objeto.
— SLaks

1
E se eu receber meus dados de um serviço remoto usando o Ajax, que me devolva a resposta do Json? E eu quero que essa resposta seja salva no objeto de matriz JavaScript?
— Mohammed Noureldin

126

Digamos que você saiba que é JSON válido, mas você ainda está recebendo isso ...

Nesse caso, é provável que haja caracteres ocultos / especiais na string de qualquer fonte que você os obtenha. Quando você cola em um validador, eles são perdidos - mas na string eles ainda estão lá. Esses caracteres, enquanto invisíveis, vão quebrarJSON.parse()

Se sé o seu JSON bruto, limpe-o com:

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

Eu estava recebendo o erro e o localizei para um caractere estranho em uma string. Eu usei seu método de remover os caracteres JSON inválidos e funcionou.
— albertski 13/08/2015

1
vieram aqui duas vezes agora. thnx
— Benjamin Hoffman

Obteve um caractere especial após a decodificação Base64, seu método me ajudou muito! Thx
— Guillaume

não confie em uma fonte que responda com JSON inválido. Apenas informe a eles que os dados estão corrompidos. eles deveriam consertar isso. se você tentar "recuperar" a resposta dessa maneira ou de maneiras semelhantes, manterá uma comunicação instável.
— Onur Yıldırım

Deve ser em s = s.replace(/[\u0000-\u001F]+/g,""); vez de s = s.replace(/[\u0000-\u0019]+/g,""); , para substituir todos os caracteres de controle. Certo?
— HongchaoZhang

63

Parece que você deseja restringir o objeto. Então faça o seguinte:

JSON.stringify(products);

A razão do erro é que JSON.parse()espera um Stringvalor e productsé um Array.

Nota: Eu acho que tenta o json.parse('[object Array]')que reclama que não esperava token odepois [.


28

Encontrei o mesmo problema com JSON.parse(inputString) .

No meu caso, a string de entrada vem da minha página do servidor [retorno de um método de página] .

Eu imprimi o typeof(inputString) - era string, ainda assim o erro ocorre.

Eu também tentei JSON.stringify(inputString) , mas não ajudou.

Mais tarde, descobri que isso era um problema com o operador de nova linha [\n] , dentro de um valor de campo.

Eu substituí [por algum outro personagem, coloque a nova linha de volta após a análise] e tudo está funcionando bem.


2
O novo caractere de linha também foi meu problema. Então, como podemos restaurar esses dados?
— precisa saber é o seguinte

@kolenda Você tem JSON inválido. Você precisa alterar seu servidor para usar um serializador JSON real que retorne JSON válido.
— SLaks

Eu tive um problema semelhante, mas em vez de "\ n" eu tinha um "\ e" dentro de um caminho (alterei o código do lado do servidor para usar "/" em vez de "\" e tudo estava funcionando novamente)
— Adam Tal

use uma fuga em que \ n seria \\ n
— Paul Gregoire

13

JSON.parse está aguardando uma String no parâmetro Você precisa especificar seu objeto JSON para resolver o problema.

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

mudar para

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 sim, o OP pode usar produtos diretamente. mas se ele quiser usar JSON.parse, os argumentos devem ser uma string.
— precisa saber é o seguinte

o que devo fazer em ASP clássico, porque "é o comentário
— ashish bhatt

1
@ashishbhatt você pode usar "e, em seguida, alterar todos os outros" para \ "
— pktangyue

2
Algo assimJSON.parse(products.replace(/'/g, '"'))
— Programador químico

10

Você deve validar sua string JSON aqui .

Uma cadeia JSON válida deve ter aspas duplas em torno das chaves:

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

Se não houver aspas, isso causará um erro:

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

O uso de aspas simples também causará um erro:

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

No meu caso, o Grails 2.5.6 renderizado render ([key: value])com aspas simples, levando ao JSON parseError na posição 1 no jquery Ajax. render (groovy.json.JsonOutput.toJson ([key:value]))me ajudou.
— 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"
  }
]

Aqui está o seu Json perfeito que você pode analisar.


3

Aqui está uma função que eu criei com base nas respostas anteriores: ela funciona na minha máquina, mas no 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

Uma outra pegadinha que pode resultar em "SyntaxError: Unexpected token"exceção ao chamar JSON.parse()está usando qualquer um dos seguintes itens nos valores da sequência:

  1. Caracteres de nova linha.

  2. Guias (sim, guias que você pode produzir com a tecla Tab!)

  3. Qualquer barra autônoma \(mas, por algum motivo /, não , pelo menos não no Chrome).

(Para uma lista completa, consulte a seção String aqui .)

Por exemplo, o seguinte exibirá essa exceção:

{
    "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"
    }
}

Portanto, deve ser alterado para:

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

O que, devo dizer, torna bastante ilegível no formato somente JSON, com maior quantidade de texto.



1

Espero que isso ajude outra pessoa.

Meu problema foi que eu havia comentado HTML em uma função de retorno de chamada PHP via AJAX que estava analisando os comentários e retornando JSON inválido.

Depois que removi o HTML comentado, tudo ficou bem e o JSON foi analisado sem problemas.


0

products é uma matriz que pode ser usada diretamente:

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

Agora, aparentemente \r, \b, \t, \f, etc não são os caracteres única problemáticas que podem lhe dar esse erro.

Observe que alguns navegadores podem ter requisitos adicionais para a entrada de JSON.parse.

Execute este código de teste no seu navegador:

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

Testando no Chrome, vejo que ele não permite JSON.parse(String.fromCharCode(0x22, x, 0x22));onde xestão 34, 92 ou de 0 a 31.

Os caracteres 34 e 92 são "e\ caracteres respectivamente, e geralmente são esperados e escapam adequadamente. Os caracteres de 0 a 31 dão a você problemas.

Para ajudar na depuração, antes de fazer JSON.parse(input) verificar, verifique primeiro se a entrada não contém caracteres problemáticos:

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

Por que você precisa do JSON.parse? Já está na matriz do formato do objeto.

Melhor usar JSON.stringify como abaixo: var b = JSON.stringify(products);

Isso pode ajudá-lo.


0

Oh, cara, as soluções em todas as respostas acima fornecidas até agora não funcionaram para mim. Eu tive um problema semelhante agora. Consegui resolvê-lo com a quebra da cotação. Veja a captura de tela. Whoo.

insira a descrição da imagem aqui

Original:

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

O erro que você está recebendo, ou seja, "token inesperado o" é porque json é esperado, mas o objeto é obtido durante a análise. Esse "o" é a primeira letra da palavra "objeto".


0

O único erro que você está cometendo é que você está analisando um objeto já analisado, então está lançando um erro, use isso e você estará pronto para prosseguir.

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

se você quiser imprimir json inteiro, use JSON.stringify ()


0

Isso pode acontecer por várias razões, mas provavelmente por um caractere inválido, para que você possa usar JSON.stringify(obj);isso transformará seu objeto em um JSON, mas lembre-se de que é uma expressão JQUERY.


0

Eu tenho esse erro porque a API que retornou o objeto json estava dando um erro (no meu caso, o Code Igniter, retorne um html quando o código php falhar), portanto, NÃO É UM OBJETO JSON.

Verifique as sentenças SQL e o código PHP e teste-o com Postman (ou algum outro testador de API)


0

O erro que eu estava cometendo foi passar null cometendo (sem saber) para JSON.parse ().

Então jogou Unexpected token n in JSON at position 0


-24

Use eval. Ele pega a expressão / código JavaScript como string e a avalia / executa.

eval(inputString);

Cada chamada de eval () cria uma nova instância do interpretador JavaScript. Isso pode ser um recurso pesado.
— Yëco 16/03/2015
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.