Tratamento de erros em chamadas getJSON

192

Como você pode lidar com erros em uma chamada getJSON? Estou tentando fazer referência a um serviço de script entre domínios usando jsonp, como você registra um método de erro?

Ajay
fonte
Ajay, por que não considerar marcar a resposta correta?
Ionică Bizău
@ IonicăBizău Marcou agora. Só perdi a noção disso por um tempo. A resposta principal não está falando sobre JSONP. Como fora apontado por Ben Shelock, não há nenhum manipulador de erro suportado é o que eu acredito ..
Ajay

Respostas:

277

$.getJSON() é um tipo de abstração de uma chamada AJAX comum, na qual você precisa informar que deseja uma resposta codificada em JSON.

$.ajax({
  url: url,
  dataType: 'json',
  data: data,
  success: callback
});

Você pode manipular erros de duas maneiras: genericamente (configurando suas chamadas AJAX antes de realmente chamá-las) ou especificamente (com cadeia de métodos).

'genérico' seria algo como:

$.ajaxSetup({
      "error":function() { alert("error");  }
});

E a maneira 'específica':

$.getJSON("example.json", function() {
  alert("success");
})
.success(function() { alert("second success"); })
.error(function() { alert("error"); })
.complete(function() { alert("complete"); });
Luciano Costa
fonte
Nops! Você pode ir como quiser lá. Dê uma olhada a documentação para ajuda mais detalhada: http://api.jquery.com/jQuery.ajax
Luciano Costa
5
Note que isto requer jQuery 1.5+ (estava tentando fazê-lo funcionar w / jQuery 1.3 e perguntando por que ele estava reclamando sobre o método inválido :-)
kenyee
24
O OP está perguntando especificamente sobre vários sites JSONP, pois parece que getJSONnesse caso não chama a error()função. Estou tendo o mesmo problema. Eu acho que tem a ver com a forma como JSONPé tratado totalmente diferente das AJAXchamadas normais , jQueryapesar de getJSONlidar com ambas. JSONé feito com um XMLHTTPRequestobjeto, mas JSONPé feito adicionando uma <script>tag dinamicamente às páginas da página HEAD.
hippietrail
3
O jQuery Doc diz "Observação: este manipulador não é chamado para solicitações de script entre domínios e JSONP". api.jquery.com/jQuery.ajax > erro
OneWorld
10
"Os métodos de retorno de chamada jqXHR.success (), jqXHR.error () e jqXHR.complete () introduzidos no jQuery 1.5 foram preteridos a partir do jQuery 1.8. Para preparar seu código para sua eventual remoção, use jqXHR.done (), jqXHR .fail () e jqXHR.always (). "
Skorunka František 16/10
86

Alguém deu a Luciano esses pontos :) Acabei de testar sua resposta - tinha uma pergunta semelhante - e funcionou perfeitamente ...

Eu até adiciono meus 50 centavos:

.error(function(jqXHR, textStatus, errorThrown) {
        console.log("error " + textStatus);
        console.log("incoming Text " + jqXHR.responseText);
    })
frenetix
fonte
3
Isso ocorreu com JSONP entre sites ou com o mesmo site JSON?
Hippietrail 18/12/11
28
Boa resposta! Apenas uma nota sobre .error: Ele vai depreciar em jQuery 1.8, então o uso .fail
Anatoly Mironov
73

Aqui está a minha adição.

De http://www.learnjavascript.co.uk/jq/reference/ajax/getjson.html e a fonte oficial

" Os métodos de retorno de chamada jqXHR.success (), jqXHR.error () e jqXHR.complete () introduzidos no jQuery 1.5 foram preteridos a partir do jQuery 1.8. Para preparar seu código para sua eventual remoção, use jqXHR.done (), jqXHR .fail () e jqXHR.always (). "

Eu fiz isso e aqui está o trecho de código atualizado de Luciano:

$.getJSON("example.json", function() {
  alert("success");
})
.done(function() { alert('getJSON request succeeded!'); })
.fail(function() { alert('getJSON request failed! '); })
.always(function() { alert('getJSON request ended!'); });

E com a descrição do erro mais mostrando todos os dados do json como uma string:

$.getJSON("example.json", function(data) {
  alert(JSON.stringify(data));
})
.done(function() { alert('getJSON request succeeded!'); })
.fail(function(jqXHR, textStatus, errorThrown) { alert('getJSON request failed! ' + textStatus); })
.always(function() { alert('getJSON request ended!'); });

Se você não gosta de alertas, substitua-os por console.log

$.getJSON("example.json", function(data) {
  console.log(JSON.stringify(data));
})
.done(function() { console.log('getJSON request succeeded!'); })
.fail(function(jqXHR, textStatus, errorThrown) { console.log('getJSON request failed! ' + textStatus); })
.always(function() { console.log('getJSON request ended!'); });
user2314737
fonte
qual é a ordem cronológica de done, fail, always e o código dentro de getJSON?
TheLogicGuy
nota: console.log não está implementado em navegadores mais antigos como o IE7! Apenas no caso de você usá-lo!
MadMad666
12

Eu sei que já faz um tempo desde que alguém respondeu aqui e o pôster provavelmente já recebeu sua resposta daqui ou de algum outro lugar. No entanto, acho que este post ajudará quem procura uma maneira de acompanhar erros e tempos limite ao fazer solicitações getJSON. Portanto, abaixo da minha resposta à pergunta

A estrutura getJSON é a seguinte (encontrada em http://api.jqueri.com ):

$(selector).getJSON(url,data,success(data,status,xhr))

a maioria das pessoas implementa esse uso

$.getJSON(url, datatosend, function(data){
    //do something with the data
});

onde eles usam o url var para fornecer um link para os dados JSON, o envio de dados como um local para adicionar as "?callback=?"e outras variáveis ​​que precisam ser enviadas para que os dados JSON corretos sejam retornados e a função de sucesso como uma função para processar os dados .

No entanto, você pode adicionar as variáveis ​​status e xhr em sua função de sucesso. A variável status contém uma das seguintes seqüências de caracteres: "success", "notmodified", "error", "timeout" ou "parsererror", e a variável xhr contém o objeto XMLHttpRequest retornado ( encontrado em w3schools )

$.getJSON(url, datatosend, function(data, status, xhr){
    if (status == "success"){
        //do something with the data
    }else if (status == "timeout"){
        alert("Something is wrong with the connection");
    }else if (status == "error" || status == "parsererror" ){
        alert("An error occured");
    }else{
        alert("datatosend did not change");
    }         
});

Dessa forma, é fácil manter o controle de tempos limite e erros sem a necessidade de implementar um rastreador de tempo limite personalizado iniciado após a solicitação.

Espero que isso ajude alguém que ainda esteja procurando uma resposta para essa pergunta.

Tom Groentjes
fonte
2
Isso não funciona. O retorno de chamada "success", como o próprio nome indica, é chamado apenas de sucesso. (Então eu não tenho certeza do que o parâmetro "status" é para ...)
jwelsh
4

$.getJSON("example.json", function() {
  alert("success");
})
.success(function() { alert("second success"); })
.error(function() { alert("error"); })

É corrigido no jQuery 2.x; No jQuery 1.x, você nunca receberá um retorno de chamada de erro

Pavlo O.
fonte
1

Fui confrontado com esse mesmo problema, mas, em vez de criar retornos de chamada para uma solicitação com falha, simplesmente retornei um erro com o objeto de dados json.

Se possível, essa parece ser a solução mais fácil. Aqui está uma amostra do código Python que eu usei. (Usando o Flask, os jsonify f e SQLAlchemy do Flask)

try:
    snip = Snip.query.filter_by(user_id=current_user.get_id(), id=snip_id).first()
    db.session.delete(snip)
    db.session.commit()
    return jsonify(success=True)
except Exception, e:
    logging.debug(e)
    return jsonify(error="Sorry, we couldn't delete that clip.")

Então você pode verificar o Javascript assim;

$.getJSON('/ajax/deleteSnip/' + data_id,
    function(data){
    console.log(data);
    if (data.success === true) {
       console.log("successfully deleted snip");
       $('.snippet[data-id="' + data_id + '"]').slideUp();
    }
    else {
       //only shows if the data object was returned
    }
});
Nick Woodhams
fonte
Isso é bom para erros que ocorrem no servidor, mas não é capturado quando a chamada não pode chegar ao servidor ou se ocorrer um erro antes de atingir o código do servidor, como se um usuário MVC não fosse mais autenticado.
Oades
1

Por que não

getJSON('get.php',{cmd:"1", typeID:$('#typesSelect')},function(data) {
    // ...
});

function getJSON(url,params,callback) {
    return $.getJSON(url,params,callback)
        .fail(function(jqXMLHttpRequest,textStatus,errorThrown) {
            console.dir(jqXMLHttpRequest);
            alert('Ajax data request failed: "'+textStatus+':'+errorThrown+'" - see javascript console for details.');
        })
}

??

Para obter detalhes sobre o .fail()método usado (jQuery 1.5+), consulte http://api.jquery.com/jQuery.ajax/#jqXHR

Como o jqXHRé retornado pela função, um encadeamento como

$.when(getJSON(...)).then(function() { ... });

é possível.

phil294
fonte
0

Em alguns casos, você pode encontrar um problema de sincronização com este método. Eu escrevi a chamada de retorno de chamada dentro de uma setTimeoutfunção e funcionou de forma síncrona muito bem =)

POR EXEMPLO:

function obterJson(callback) {


    jqxhr = $.getJSON(window.location.href + "js/data.json", function(data) {

    setTimeout(function(){
        callback(data);
    },0);
}
Alex Alonso
fonte