A solicitação Ajax retorna 200 OK, mas um evento de erro é acionado em vez de bem-sucedido

805

Eu implementei uma solicitação Ajax no meu site e estou chamando o terminal de uma página da web. Ele sempre retorna 200 OK , mas o jQuery executa o evento de erro.
Eu tentei muitas coisas, mas não consegui descobrir o problema. Estou adicionando meu código abaixo:

Código jQuery

var row = "1";
var json = "{'TwitterId':'" + row + "'}";
$.ajax({
    type: 'POST',
    url: 'Jqueryoperation.aspx?Operation=DeleteRow',
    contentType: 'application/json; charset=utf-8',
    data: json,
    dataType: 'json',
    cache: false,
    success: AjaxSucceeded,
    error: AjaxFailed
});
function AjaxSucceeded(result) {
    alert("hello");
    alert(result.d);
}
function AjaxFailed(result) {
    alert("hello1");
    alert(result.status + ' ' + result.statusText);
}

Código c # para JqueryOpeartion.aspx

protected void Page_Load(object sender, EventArgs e) {
    test();
}
private void test() {
    Response.Write("<script language='javascript'>alert('Record Deleted');</script>");
}

Preciso da ("Record deleted")string após a exclusão bem-sucedida. Consigo excluir o conteúdo, mas não estou recebendo esta mensagem. Isso está correto ou estou fazendo algo errado? Qual é a maneira correta de resolver esse problema?

Pankaj Mishra
fonte
2
Você pode executar a saída de JqueryOperation.aspx através de um validador JSON e ver se ele JSON válida
parapura rajkumar
1
Como jsonlint.com . Você também precisa verificar os parâmetros que envia. Atualmente, você não definiu nenhum nome de parâmetro. Se o parâmetro for TwitterId, então você tem que passar um objeto para data, não uma string: data: {TwitterId: row}.
Felix Kling
6
A página Jqueryoperation.aspx retorna JSON (válido)?
Salman A
1
provavelmente o código do lado do servidor está lançando uma exceção .. o que você está retornando no seu bloco de captura como resposta?
Raghav 31/05
3
@Raghav, se o servidor lançou uma exceção ao processar a solicitação, o código de retorno HTTP seria 500.
StuperUser

Respostas:

1118

jQuery.ajaxtenta converter o corpo da resposta, dependendo do dataTypeparâmetro especificado ou do Content-Typecabeçalho enviado pelo servidor. Se a conversão falhar (por exemplo, se o JSON / XML for inválido), o retorno de chamada de erro será acionado.


Seu código AJAX contém:

dataType: "json"

Nesse caso, jQuery:

Avalia a resposta como JSON e retorna um objeto JavaScript. […] Os dados JSON são analisados ​​de maneira estrita; qualquer JSON malformado é rejeitado e um erro de análise é gerado. […] Uma resposta vazia também é rejeitada; o servidor deve retornar uma resposta nula ou {}.

Seu código do lado do servidor retorna um snippet HTML com 200 OKstatus. O jQuery esperava JSON válido e, portanto, aciona o retorno de chamada de erro queixando-se parseerror.

A solução é remover o dataTypeparâmetro do seu código jQuery e fazer com que o código do lado do servidor retorne:

Content-Type: application/javascript

alert("Record Deleted");

Mas eu prefiro sugerir o retorno de uma resposta JSON e exibir a mensagem dentro do retorno de chamada de sucesso:

Content-Type: application/json

{"message": "Record deleted"}
Salman A
fonte
1
Obrigado pela sua resposta, você pode me dizer uma coisa, como posso retornar o valor json do código por trás. Estou usando o asp.net com c #. Isso resolveu o meu problema, mas também pode me informar sobre isso.
Pankaj Mishra
1
@Pankaj: é melhor se você publicá-lo como outra pergunta. Mas resposta curta: duas maneiras de fazer isso (i) em vez de $.ajaxvocê pode tentar $.getScript. Dentro do script C # do lado do servidor, basta colocar alert('Record Deleted');(sem <script>tag) e definir o ContentType do seu script C # para text/javascript. $.ajaxtambém pode funcionar, mas não me lembro como, pode ser que você só precise mudar dataType: 'script',. Você pode não precisar mais do manipulador de sucesso.
Salman A
3
Esta resposta pode não estar completa. Agora que eu validei meu JSON em jsonlint.com, ele diz explicitamente que é um vaild json, mas ainda assim o evento "error" foi acionado, com o xhr.status 200. que outras razões podem estar lá? - Ramesh Pareek edit agora
Ramesh Pareek
2
Ou você pode simplesmente excluir o parâmetro "dataType: json"
Piero Alberto
1
Corri para o mesmo problema sem especificar um tipo de dados ao usar $.post. Nesse caso, o jquery adivinha um tipo de dados e os erros quando falha ao analisar . Esta é uma pegadinha realmente desagradável e difícil de encontrar. Eu o corrigi definindo o tipo de dados para "text".
Mashmagar 31/03/19
31

Eu tive sorte com o uso de vários dataTypes separados por espaço ( jQuery 1.5+ ). Como em:

$.ajax({
    type: 'POST',
    url: 'Jqueryoperation.aspx?Operation=DeleteRow',
    contentType: 'application/json; charset=utf-8',
    data: json,
    dataType: 'text json',
    cache: false,
    success: AjaxSucceeded,
    error: AjaxFailed
});
jaketrent
fonte
1
Com base na documentação do JQuery, da mesma forma, uma string abreviada como "jsonp xml" tentará primeiro converter de jsonp para xml e, na sua falta, converter de jsonp em texto e, em seguida, de texto em xml. Portanto, ele tentará ocultar o texto para o json primeiro e, se falhar, será tratado como texto?
anIBMer
29

Você simplesmente precisa remover o dataType: "json" na sua chamada AJAX

$.ajax({
    type: 'POST',
    url: 'Jqueryoperation.aspx?Operation=DeleteRow',
    contentType: 'application/json; charset=utf-8',
    data: json,
    dataType: 'json', //**** REMOVE THIS LINE ****//
    cache: false,
    success: AjaxSucceeded,
    error: AjaxFailed
});
Philippe Genois
fonte
22

Isso é apenas para constar desde que me deparei com este post ao procurar uma solução para o meu problema que fosse semelhante aos do OP.

No meu caso, minha solicitação do jQuery Ajax foi impedida devido à política de mesma origem no Chrome. Tudo foi resolvido quando modifiquei meu servidor (Node.js) para:

response.writeHead(200,
          {
            "Content-Type": "application/json",
            "Access-Control-Allow-Origin": "http://localhost:8080"
        });

Literalmente, me custou uma hora batendo com a cabeça na parede. Estou me sentindo estúpido ...

Corvin
fonte
1
Obrigado Peter, tive o mesmo problema e a mensagem de aviso no console do navegador está confusa para mim. Tanto quanto eu sei que o CORS bloqueia a solicitação de envio (usando o método de negociação de opções), não faz sentido esse bloco após a operação após a conclusão. Talvez seja um comportamento de navegador personalizado .. Eu testei com o Firefox. Obrigado, sua solução resolveu meu problema.
Danipenaperez 18/06/19
15

Eu acho que sua página aspx não retorna um objeto JSON. Sua página deve fazer algo assim (page_load)

var jSon = new JavaScriptSerializer();
var OutPut = jSon.Serialize(<your object>);

Response.Write(OutPut);

Além disso, tente alterar seu AjaxFailed:

function AjaxFailed (XMLHttpRequest, textStatus) {

}

textStatus deve fornecer o tipo de erro que você está recebendo.

LeftyX
fonte
12

Eu enfrentei esse problema com uma biblioteca jQuery atualizada. Se o método de serviço não retornar nada, isso significa que o tipo de retorno évoid .

Em sua chamada do Ajax, mencione dataType='text' .

Isso resolverá o problema.

Suresh Vadlakonda
fonte
8

Você apenas precisa remover dataType: 'json' do cabeçalho se o método de serviço da Web implementado for nulo.

Nesse caso, a chamada Ajax não espera ter um tipo de dados de retorno JSON.

Bilel omrani
fonte
4

Use o código a seguir para garantir que a resposta esteja no formato JSON (versão PHP) ...

header('Content-Type: application/json');
echo json_encode($return_vars);
exit;
Terry Lin
fonte
4

Eu tive o mesmo problema. Meu problema foi que meu controlador estava retornando um código de status em vez de JSON. Certifique-se de que seu controlador retorne algo como:

public JsonResult ActionName(){
   // Your code
   return Json(new { });
}
Alexander Suleymanov
fonte
3

Eu tenho o problema semelhante, mas quando tentei remover o tipo de dados: 'json' ainda tenho o problema. Meu erro está sendo executado em vez do sucesso

function cmd(){
    var data = JSON.stringify(display1());
    $.ajax({
        type: 'POST',
        url: '/cmd',
        contentType:'application/json; charset=utf-8',
        //dataType:"json",
        data: data,
        success: function(res){
                  console.log('Success in running run_id ajax')
                  //$.ajax({
                   //   type: "GET",
                   //   url: "/runid",
                   //   contentType:"application/json; charset=utf-8",
                   //   dataType:"json",
                   //   data: data,
                   //  success:function display_runid(){}
                  // });
        },
        error: function(req, err){ console.log('my message: ' + err); }
    });
}
Rakesh Kumar
fonte
Eu estou vendo a mesma coisa. A resposta vazia com um código 200 ainda está acionando o manipulador de erros.
doublejosh
2

Outra coisa que atrapalhou as coisas para mim foi usar em localhostvez de 127.0.0.1 ou vice-versa. Aparentemente, o JavaScript não pode manipular solicitações de uma para a outra.

Paulo
fonte
2

Veja isso . É também um problema semelhante. Trabalhando eu tentei.

Não remova dataType: 'JSON',

Nota: echo apenas o formato JSON no arquivo PHP se você usar apenas php echo seu código ajax retornará 200

Inderjeet
fonte
1

Eu tive o mesmo problema. Como minha resposta JSON contém alguns caracteres especiais e o arquivo do servidor não foi codificado com UTF-8, a chamada Ajax considerou que essa não era uma resposta JSON válida.

Mehdi Izcool
fonte
1

Se você sempre retornar JSON do servidor (sem respostas vazias), dataType: 'json'deve funcionar e contentTypenão é necessário. No entanto, verifique se a saída JSON ...

O jQuery AJAX lançará um 'parseerror' em JSON válido, mas não serializado!

Fabian von Ellerts
fonte
-1

Seu script exige um retorno no tipo de dados JSON.

Tente o seguinte:

private string test() {
  JavaScriptSerializer js = new JavaScriptSerializer();
 return js.Serialize("hello world");
}
Kashif Faraz
fonte
-9

Tente seguir

$.ajax({
    type: 'POST',
    url: 'Jqueryoperation.aspx?Operation=DeleteRow',
    contentType: 'application/json; charset=utf-8',
    data: { "Operation" : "DeleteRow", 
            "TwitterId" : 1 },
    dataType: 'json',
    cache: false,
    success: AjaxSucceeded,
    error: AjaxFailed
});

OU

$.ajax({
    type: 'POST',
    url: 'Jqueryoperation.aspx?Operation=DeleteRow&TwitterId=1',
    contentType: 'application/json; charset=utf-8',
    dataType: 'json',
    cache: false,
    success: AjaxSucceeded,
    error: AjaxFailed
});

Use aspas duplas em vez de aspas simples no objeto JSON. Eu acho que isso resolverá o problema.

Salman Riaz
fonte