简体   繁体   English

使用JSONP时,如何捕获jQuery $ .getJSON(或$ .ajax,数据类型设置为'jsonp')错误?

[英]How do I catch jQuery $.getJSON (or $.ajax with datatype set to 'jsonp') error when using JSONP?

Is it possible to catch an error when using JSONP with jQuery? 结合使用JSONP和jQuery时是否可能捕获错误? I've tried both the $.getJSON and $.ajax methods but neither will catch the 404 error I'm testing. 我已经尝试了$ .getJSON和$ .ajax方法,但是都不会捕获我正在测试的404错误。 Here is what I've tried (keep in mind that these all work successfully, but I want to handle the case when it fails): 这是我尝试过的方法(请记住,这些方法都可以成功运行,但是在失败时我要处理):

jQuery.ajax({
    type: "GET",
    url: handlerURL,
    dataType: "jsonp",
    success: function(results){
        alert("Success!");
    },
    error: function(XMLHttpRequest, textStatus, errorThrown){
        alert("Error");
    }
});

And also: 并且:

jQuery.getJSON(handlerURL + "&callback=?", 
    function(jsonResult){
        alert("Success!");
    });

I've also tried adding the $.ajaxError but that didn't work either: 我也尝试过添加$ .ajaxError,但是那也不起作用:

jQuery(document).ajaxError(function(event, request, settings){
   alert("Error");
});

Thanks in advance for any replies! 预先感谢您的任何答复!

Here 's my extensive answer to a similar question. 是我对类似问题的广泛回答。

Here's the code: 这是代码:

jQuery.getJSON(handlerURL + "&callback=?", 
    function(jsonResult){
        alert("Success!");
    })
.done(function() { alert('getJSON request succeeded!'); })
.fail(function(jqXHR, textStatus, errorThrown) { alert('getJSON request failed! ' + textStatus); })
.always(function() { alert('getJSON request ended!'); });

It seems that JSONP requests that don't return a successful result never trigger any event, success or failure, and for better or worse that's apparently by design. 似乎不返回成功结果的JSONP请求永远不会触发任何事件,成功或失败,无论好坏,这显然是设计使然。

After searching their bug tracker, there's a patch which may be a possible solution using a timeout callback. 搜索他们的错误跟踪器后,有一个补丁程序可能是使用超时回调的解决方案。 See bug report #3442 . 请参阅错误报告#3442 If you can't capture the error, you can at least timeout after waiting a reasonable amount of time for success. 如果无法捕获该错误,则至少可以在等待一段合理的时间后才能成功。

Detecting JSONP problems 检测JSONP问题

If you don't want to download a dependency, you can detect the error state yourself. 如果您不想下载依赖项,则可以自己检测错误状态。 It's easy. 这很容易。

You will only be able to detect JSONP errors by using some sort of timeout. 您将只能使用某种超时来检测JSONP错误。 If there's no valid response in a certain time, then assume an error. 如果在一定时间内没有有效的响应,则假定有一个错误。 The error could be basically anything, though. 该错误基本上可以是任何东西。

Here's a simple way to go about checking for errors. 这是检查错误的简单方法。 Just use a success flag: 只需使用success标志:

var success = false;

$.getJSON(url, function(json) {
    success = true;
    // ... whatever else your callback needs to do ...
});

// Set a 5-second (or however long you want) timeout to check for errors
setTimeout(function() {
    if (!success)
    {
        // Handle error accordingly
        alert("Houston, we have a problem.");
    }
}, 5000);

As thedawnrider mentioned in comments, you could also use clearTimeout instead: 就像注释中提到的thedawnrider一样,您也可以改用clearTimeout:

var errorTimeout = setTimeout(function() {
    if (!success)
    {
        // Handle error accordingly
        alert("Houston, we have a problem.");
    }
}, 5000);

$.getJSON(url, function(json) {
    clearTimeout(errorTimeout);
    // ... whatever else your callback needs to do ...
});

Why? 为什么? Read on... 继续阅读...


Here's how JSONP works in a nutshell: 简而言之,这就是JSONP的工作方式:

JSONP doesn't use XMLHttpRequest like regular AJAX requests. JSONP不像常规AJAX请求那样使用XMLHttpRequest。 Instead, it injects a <script> tag into the page, where the "src" attribute is the URL of the request. 而是将<script>标记注入页面,其中“ src”属性是请求的URL。 The content of the response is wrapped in a Javascript function which is then executed when downloaded. 响应的内容包装在Javascript函数中,然后在下载时执行。

For example. 例如。

JSONP request: https://api.site.com/endpoint?this=that&callback=myFunc JSONP请求: https://api.site.com/endpoint?this=that&callback=myFunc ://api.site.com/endpoint https://api.site.com/endpoint?this=that&callback=myFunc this https://api.site.com/endpoint?this=that&callback=myFunc that https://api.site.com/endpoint?this=that&callback=myFunc callback https://api.site.com/endpoint?this=that&callback=myFunc myFunc

Javascript will inject this script tag into the DOM: Javascript会将以下脚本标记注入DOM:

<script src="https://api.site.com/endpoint?this=that&callback=myFunc"></script>

What happens when a <script> tag is added to the DOM? <script>标记添加到DOM时会发生什么? Obviously, it gets executed. 显然,它被执行了。

So suppose the response to this query yielded a JSON result like: 因此,假设对此查询的响应产生了JSON结果,例如:

{"answer":42}

To the browser, that's the same thing as a script's source, so it gets executed. 对于浏览器,这与脚本的源代码是一样的,因此它可以执行。 But what happens when you execute this: 但是执行此操作会发生什么:

<script>{"answer":42}</script>

Well, nothing. 好吧,什么都没有。 It's just an object. 这只是一个对象。 It doesn't get stored, saved, and nothing happens. 它不会被存储,保存,什么也不会发生。

This is why JSONP requests wrap their results in a function. 这就是为什么JSONP请求将其结果包装在一个函数中的原因。 The server, which must support JSONP serialization, sees the callback parameter you specified, and returns this instead: 必须支持JSONP序列化的服务器会看到您指定的callback参数,并返回此参数:

myFunc({"answer":42})

Then this gets executed instead: 然后执行该命令:

<script>myFunc({"answer":42})</script>

... which is much more useful. ...更加有用。 Somewhere in your code is, in this case, a global function called myFunc : 在这种情况下,代码中的某个地方是一个名为myFunc的全局函数:

myFunc(data)
{
    alert("The answer to life, the universe, and everything is: " + data.answer);
}

That's it. 而已。 That's the "magic" of JSONP. 这就是JSONP的“魔力”。 Then to build in a timeout check is very simple, like shown above. 如上图所示,建立超时检查非常简单。 Make the request and immediately after, start a timeout. 发出请求,然后立即开始超时。 After X seconds, if your flag still hasn't been set, then the request timed out. X秒钟后,如果您的标记仍未设置,则请求超时。

I know this question is a little old but I didn't see an answer that gives a simple solution to the problem so I figured I would share my 'simple' solution. 我知道这个问题有点老了,但是我没有看到可以简单解决问题的答案,所以我想我会分享我的“简单”解决方案。

$.getJSON("example.json", function() {
      console.log( "success" );
}).fail(function() { 
      console.log( "error" ); 
}); 

We can simply use the .fail() callback to check to see if an error occurred. 我们可以简单地使用.fail()回调来检查是否发生错误。

Hope this helps :) 希望这可以帮助 :)

If you collaborate with the provider, you could send another query string parameter being the function to callback when there's an error. 如果与提供者合作,则可以发送另一个查询字符串参数,该参数是发生错误时要回调的函数。

?callback=?&error=? ?callback =?&error =?

This is called JSONPE but it's not at all a defacto standard. 这被称为JSONPE,但这根本不是事实上的标准。

The provider then passes information to the error function to help you diagnose. 然后,提供程序将信息传递给错误功能以帮助您进行诊断。

Doesn't help with comm errors though - jQuery would have to be updated to also callback the error function on timeout, as in Adam Bellaire's answer. 但是,这对于解决通讯错误没有帮助-jQuery必须进行更新以在超时时回调错误函数,就像Adam Bellaire的回答一样。

Seems like this is working now: 好像现在正在工作:

jQuery(document).ajaxError(function(event, request, settings){
   alert("Error");
});

I use this to catch an JSON error 我用它来捕获JSON错误

try {
   $.getJSON(ajaxURL,callback).ajaxError();
} catch(err) {
   alert("wow");
   alert("Error : "+ err);
}

Edit: Alternatively you can get the error message also. 编辑:或者,您也可以获取错误消息。 This will let you know what the error is exactly. 这将使您知道确切的错误。 Try following syntax in catch block 尝试在catch块中遵循以下语法

alert("Error : " + err);

Mayby this works? 也许这行得通吗?

.complete(function(response, status) {
    if (response.status == "404")
        alert("404 Error");
    else{
        //Do something
    }   
    if(status == "error")
        alert("Error");
    else{
        //Do something
    }
});

I dont know whenever the status goes in "error" mode. 我不知道状态何时进入“错误”模式。 But i tested it with 404 and it responded 但是我用404测试了它

you ca explicitly handle any error number by adding this attribute in the ajax request: 您可以通过在ajax请求中添加此属性来显式处理任何错误号:

statusCode: {
        404: function() {
          alert("page not found");
        }
    }

so, your code should be like this: 因此,您的代码应如下所示:

jQuery.ajax({
type: "GET",
statusCode: {
        404: function() {
          alert("page not found");
        }
},
url: handlerURL,
dataType: "jsonp",
success: function(results){
    alert("Success!");
},
error: function(XMLHttpRequest, textStatus, errorThrown){
    alert("Error");
}
});

hope this helps you :) 希望这对您有帮助:)

I also posted this answer in stack overflow - Error handling in getJSON calls 我也在堆栈溢出中发布了此答案-getJSON调用中的错误处理

I know it's been a while since someone answerd here and the poster probably already got his answer either from here or from somewhere else. 我知道已经有一段时间了,因为有人在这里回答,而发帖人可能已经从这里或其他地方得到了他的答案。 I do however think that this post will help anyone looking for a way to keep track of errors and timeouts while doing getJSON requests. 但是,我确实认为,这篇文章将对任何寻求在执行getJSON请求时跟踪错误和超时的方法的人有所帮助。 Therefore below my answer to the question 因此,在我对问题的回答之下

The getJSON structure is as follows (found on http://api.jqueri.com ): getJSON结构如下(位于http://api.jqueri.com上 ):

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

most people implement that using 大多数人使用

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

where they use the url var to provide a link to the JSON data, the datatosend as a place to add the "?callback=?" 他们使用url var提供指向JSON数据的链接,而datatosend作为添加"?callback=?" and other variables that have to be send to get the correct JSON data returned, and the success funcion as a function for processing the data. 以及必须发送以获取返回的正确JSON数据的其他变量,以及将成功函数用作处理数据的函数。

You can however add the status and xhr variables in your success function. 但是,您可以在成功函数中添加status和xhr变量。 The status variable contains one of the following strings : "success", "notmodified", "error", "timeout", or "parsererror", and the xhr variable contains the returned XMLHttpRequest object ( found on w3schools ) 状态变量包含以下字符串之一:“成功”,“未修改”,“错误”,“超时”或“ parsererror”,而xhr变量包含返回的XMLHttpRequest对象( 在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");
    }         
});

This way it is easy to keep track of timeouts and errors without having to implement a custom timeout tracker that is started once a request is done. 这样,就很容易跟踪超时和错误,而不必实现在请求完成后启动的自定义超时跟踪器。

Hope this helps someone still looking for an answer to this question. 希望这可以帮助仍在寻找该问题答案的人。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM