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

coiso
fonte
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.

SLaks
fonte
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);
EdH
fonte
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 [.

Onur Yıldırım
fonte
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.

Derin
fonte
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
Térence
fonte
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"}]';
pktangyue
fonte
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
hoogw
fonte
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.

San
fonte
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;
            }
tmurphree
fonte
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.

c00000fd
fonte
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.

Chris
fonte
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]);
ic3b3rg
fonte
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;
        }
    }
}
Pacerier
fonte
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.

abhijit padhy
fonte
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

Well Smith
fonte
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".

Shashank Bodkhe
fonte
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 ()

Kiran Maniya
fonte
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.

Elvis Silva Noleto
fonte
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)

Ari Waisberg
fonte
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

Aashutosh Rathi
fonte
-24

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

eval(inputString);
Kasthuri
fonte
Cada chamada de eval () cria uma nova instância do interpretador JavaScript. Isso pode ser um recurso pesado.
Yëco 16/03/2015