jQuery retornando "parsererror" para solicitação de ajax

186

Obtendo um "parsererror" do jquery para uma solicitação do Ajax, tentei alterar o POST para um GET, retornando os dados de algumas maneiras diferentes (criando classes, etc.), mas não consigo descobrir qual é o problema.

Meu projeto está no MVC3 e estou usando o jQuery 1.5. Tenho um menu suspenso e, no evento onchange, aciono uma chamada para obter alguns dados com base no que foi selecionado.

Dropdown: (carrega as "Views" da lista no Viewbag e disparar o evento funciona bem)

@{
    var viewHtmls = new Dictionary<string, object>();
    viewHtmls.Add("data-bind", "value: ViewID");
    viewHtmls.Add("onchange", "javascript:PageModel.LoadViewContentNames()");
}
@Html.DropDownList("view", (List<SelectListItem>)ViewBag.Views, viewHtmls)

Javascript:

this.LoadViewContentNames = function () {
    $.ajax({
        url: '/Admin/Ajax/GetViewContentNames',
        type: 'POST',
        dataType: 'json',
        data: { viewID: $("#view").val() },
        success: function (data) {
            alert(data);
        },
        error: function (data) {
            debugger;
            alert("Error");
        }
    });
};

O código acima chama com sucesso o método MVC e retorna:

[{"ViewContentID":1,"Name":"TopContent","Note":"Content on the top"},
 {"ViewContentID":2,"Name":"BottomContent","Note":"Content on the bottom"}]

Mas o jquery dispara o evento de erro para o método $ .ajax () que diz "parsererror".

dkarzon
fonte
dispara um erro de javascript no console ou a função de manipulador "error" do comando $ .ajax () é executada?
arnorhs
desculpe, deveria ter sido mais específico, ele dispara a função de erro $ .ajax () {alert ("Error"); }
dkarzon 21/02
Alguma chance de um link ao vivo? Você vê os dados JSON exibidos no Firebug?
Pekka
Não, eu não tenho um link ao vivo. Mas sim, essa é a resposta JSON mostrada no Firebug.
dkarzon
sim, meu erro foi um erro de digitação. Corrigida a questão
dkarzon

Respostas:

306

Encontrei recentemente esse problema e me deparei com essa pergunta.

Eu resolvi isso de uma maneira muito mais fácil.

Método Um

Você pode remover a dataType: 'json'propriedade do literal do objeto ...

Método dois

Ou você pode fazer o que @Sagiv estava dizendo retornando seus dados como Json.


A razão pela qual essa parsererrormensagem ocorre é que, quando você simplesmente retorna uma sequência ou outro valor, não é realmente Json, portanto o analisador falha ao analisá-la.

Portanto, se você remover a dataType: jsonpropriedade, ela não tentará analisá-la como Json.

Com o outro método, se você retornar seus dados como Json, o analisador saberá como manipulá-los adequadamente.

David East
fonte
4
Obrigado David, o Método Um funcionou para mim. No meu caso, eu não estava retornando nada, mas usei um tipo de dados por engano. Obrigado pela dica.
Krishna Teja Veeramachaneni
Obrigado pela resposta, atualizei a resposta para a missão, pois esta parece ser uma solução melhor.
dkarzon
Encontrei esse problema quando meu script php teve um erro e estava retornando dados não JSON - uma sugestão útil para desativar de dataType fato!
Sharadh 14/05
Obrigado! Isso se aplica também ao jquery.fileupload.js e outras bibliotecas usando os métodos JQuery AJAX. Mensagem de erro confusa!
kqr
Estou recebendo esse problema usando o Rails jquery-ujs
Donato
29

Veja a resposta de @ david-east para a maneira correta de lidar com o problema

Esta resposta é relevante apenas para um bug do jQuery 1.5 ao usar o arquivo: protocolo.

Recentemente, tive um problema semelhante ao atualizar para o jQuery 1.5. Apesar de obter uma resposta correta, o manipulador de erros foi acionado. Eu o resolvi usando o completeevento e depois verificando o valor do status. por exemplo:

complete: function (xhr, status) {
    if (status === 'error' || !xhr.responseText) {
        handleError();
    }
    else {
        var data = xhr.responseText;
        //...
    }
}
johnhunter
fonte
1
Confirmado corrigido no JQuery 1.5.1
johnhunter
13
Eu tenho esse problema em 1.7.2 :(
Eystein Bye
6
Eu estava tendo esse problema, mas removi o tipo de dados: 'json' e o problema foi resolvido. Como não está retornando uma forma verdadeira de um json, ele encontrará um erro no analisador.
David East
3
Estou tendo esse problema na versão 1.9.1 e resolvi fazer com que minha API retornasse um hash vazio {}. Pena que isso é necessário.
Adam Tuttle
4
Esta é realmente na documentação: ...The JSON data is parsed in a strict manner; any malformed JSON is rejected and a parse error is thrown. As of jQuery 1.9, an empty response is also rejected; the server should return a response of null or {} instead. api.jquery.com/jQuery.ajax
Rob
17

Você especificou o dataType de resposta de chamada ajax como:

'json'

onde a resposta ajax real não é um JSON válido e, como resultado, o analisador JSON está lançando um erro.

A melhor abordagem que eu recomendaria é alterar o dataType para:

'texto'

e dentro do retorno de chamada bem-sucedido, valide se um JSON válido está sendo retornado ou não e, se a validação do JSON falhar, alerte-o na tela para que fique óbvio para que finalidade a chamada ajax está realmente falhando. Veja isso:

$.ajax({
    url: '/Admin/Ajax/GetViewContentNames',
    type: 'POST',
    dataType: 'text',
    data: {viewID: $("#view").val()},
    success: function (data) {
        try {
            var output = JSON.parse(data);
            alert(output);
        } catch (e) {
            alert("Output is not valid JSON: " + data);
        }
    }, error: function (request, error) {
        alert("AJAX Call Error: " + error);
    }
});
Nadeem Khan
fonte
1
ou remover o tipo de dados :)
Alexander
10

o problema é que seu controlador retorna uma string ou outro objeto que não pode ser analisado. a chamada ajax esperava receber Json em troca. tente retornar JsonResult no controlador assim:

 public JsonResult YourAction()
    {
        ...return Json(YourReturnObject);

    }

espero que ajude :)

Sagiv Ofek
fonte
Desculpe, esqueci de incluir meu código por trás, mas é exatamente assim que o Json é retornado.
dkarzon
4

Existem muitas sugestões para remover

dataType: "json"

Embora eu conceda que isso funcione, ignore o problema subjacente. Se você está confiante de que a sequência de retorno realmente é JSON, procure espaços em branco incorretos no início da resposta. Considere dar uma olhada no violinista. O meu ficou assim:

Connection: Keep-Alive
Content-Type: application/json; charset=utf-8

{"type":"scan","data":{"image":".\/output\/ou...

No meu caso, houve um problema com o PHP expelindo caracteres indesejados (nesse caso, BOMs de arquivo UTF). Depois que eu os removi, ele corrigiu o problema, mantendo

dataType: json
Sam Strachan
fonte
Concordo com isso ... verifiquei a resposta e foi um var_dump () que foi perdido em algum lugar do aplicativo.
Chuck
2

Certifique-se de remover qualquer código de depuração ou qualquer outra coisa que possa estar gerando informações indesejadas. Um tanto óbvio, mas fácil de esquecer no momento.

Jahmic
fonte
0

Eu não sei se isso ainda é real, mas o problema estava com a codificação. Mudar para ANSI resolveu o problema para mim.

George Dgebuadze
fonte
0

Se você tiver esse problema usando HTTP GET no IE, resolvi esse problema configurando o cache: false. Como usei o mesmo URL para solicitações HTML e json, ele atingiu o cache em vez de fazer uma chamada json.

$.ajax({
    url: '/Test/Something/',
    type: 'GET',
    dataType: 'json',
    cache: false,
    data: { viewID: $("#view").val() },
    success: function (data) {
        alert(data);
    },
    error: function (data) {
        debugger;
        alert("Error");
    }
});
Stuart
fonte
0

você deve remover o dataType: "json". Então veja a mágica ... o motivo de fazer isso é que você está convertendo o objeto json em uma sequência simples ... para que o json parser não possa analisar essa sequência por não ser um objeto json.

this.LoadViewContentNames = function () {
$.ajax({
    url: '/Admin/Ajax/GetViewContentNames',
    type: 'POST',
    data: { viewID: $("#view").val() },
    success: function (data) {
        alert(data);
    },
    error: function (data) {
        debugger;
        alert("Error");
    }
 });
};
Desi boys
fonte
0

No caso da operação Get da web .net mvc / api, certifique-se de permitir obter

     return Json(data,JsonRequestBehavior.AllowGet);
Mohamed.Abdo
fonte
0

Eu também estava recebendo "Solicitação de retorno com erro: parsererror". no console javascript. No meu caso, não era problema do Json, mas tive que passar para a área de texto da visualização uma codificação válida.

  String encodedString = getEncodedString(text, encoding);
  view.setTextAreaContent(encodedString);
Laura Liparulo
fonte
0

Eu encontrei esse erro, mas depois de modificar minha resposta antes de enviá-la ao cliente, ela funcionou bem.

//Server side
response = JSON.stringify('{"status": {"code": 200},"result": '+ JSON.stringify(result)+'}');
res.send(response);  // Sending to client

//Client side
success: function(res, status) {
    response = JSON.parse(res); // Getting as expected
    //Do something
}
Ananth Kumar Vasamsetti
fonte
0

Eu tive o mesmo problema, acabou que o meu web.confignão era o mesmo com meus colegas de equipe. Então, por favor, verifique o seu web.config.

Espero que isso ajude alguém.

Roshna Omer
fonte
-1

O problema

window.JSON.parse gera um erro na função $ .parseJSON.

<pre>
$.parseJSON: function( data ) {
...
// Attempt to parse using the native JSON parser first
if ( window.JSON && window.JSON.parse ) {
return window.JSON.parse( data );
}
...
</pre>

Minha solução

Sobrecarregando o JQuery usando a ferramenta requirejs .

<pre>
define(['jquery', 'jquery.overload'], function() { 
    //Loading jquery.overload
});
</pre>

conteúdo do arquivo jquery.overload.js

<pre>
define(['jquery'],function ($) { 

    $.parseJSON: function( data ) {
        // Attempt to parse using the native JSON parser first
        /**  THIS RAISES Parsing ERROR
        if ( window.JSON && window.JSON.parse ) {
            return window.JSON.parse( data );
        }
        **/

        if ( data === null ) {
            return data;
        }

        if ( typeof data === "string" ) {

            // Make sure leading/trailing whitespace is removed (IE can't handle it)
            data = $.trim( data );

            if ( data ) {
                // Make sure the incoming data is actual JSON
                // Logic borrowed from http://json.org/json2.js
                if ( rvalidchars.test( data.replace( rvalidescape, "@" )
                    .replace( rvalidtokens, "]" )
                    .replace( rvalidbraces, "")) ) {

                    return ( new Function( "return " + data ) )();
                }
            }
        }

        $.error( "Invalid JSON: " + data );
    }

    return $;

});
</pre>
Christian MEROUR
fonte
-1

Se você não deseja remover / alterardataType: json , é possível substituir a análise rigorosa do jQuery definindo um costume converter:

$.ajax({
    // We're expecting a JSON response...
    dataType: 'json',

    // ...but we need to override jQuery's strict JSON parsing
    converters: {
        'text json': function(result) {
            try {
                // First try to use native browser parsing
                if (typeof JSON === 'object' && typeof JSON.parse === 'function') {
                    return JSON.parse(result);
                } else {
                    // Fallback to jQuery's parser
                    return $.parseJSON(result);
                }
            } catch (e) {
               // Whatever you want as your alternative behavior, goes here.
               // In this example, we send a warning to the console and return 
               // an empty JS object.
               console.log("Warning: Could not parse expected JSON response.");
               return {};
            }
        }
    },

    ...

Usando isso, você pode personalizar o comportamento quando a resposta não puder ser analisada como JSON (mesmo se você receber um corpo de resposta vazio!)

Com este conversor personalizado, .done()/ successserá acionado enquanto a solicitação tiver sido bem-sucedida (código de resposta 1xx ou 2xx).

alexw
fonte