如何用jQuery在JSON ajax请求中的404上回调函数?

时间:2022-11-29 13:39:27

I want to make an Ajax request with response in JSON. So I made this Ajax request:

我想发出一个JSON响应的Ajax请求。所以我提出了Ajax请求:

$.ajax({
    url: 'http://my_url',
    dataType: "json",
    success: function(data){
      alert('success');
    },
    error: function(data){
      alert('error');
    },
    complete: function(data) {
      alert('complete')
    }})

This code works good but when my url send me a HTTP code 404, no callbacks are used, even the complete callback. After research, it's because my dataType is 'json' so 404 return is HTML and the JSON parsing failed. So no callback.

这段代码运行良好,但是当我的url发送给我一个HTTP代码404时,不使用回调,甚至是完整的回调。研究之后,因为我的数据类型是“json”,所以404返回是HTML, json解析失败。所以没有回调。

Have you a solution to call a callback function when a 404 is raised ?

您是否有一个解决方案,当404被提出时调用回调函数?

EDIT: complete callback don't call is return is 404. If you want an URL wit 404 you can call : http://twitter.com/status/user_timeline/jksqdlmjmsd.json?count=3&callback=jsonp1269278524295&_=1269278536697 it's with this URL I have my problem.

编辑:完全回调不调用是返回404。如果您想要一个URL wit 404,可以调用:http://twitter.com/status/user_timeline/jksqdlmjmsd.json?count=3&callback=jsonp1269278524295&_=1269278536697这个URL有问题。

10 个解决方案

#1


19  

$.ajax({
    url: 'http://twitter.com/status/user_timeline/jksqdlmjmsd.json?count=3&callback=jsonp1269278524295&_=1269278536697',
    dataType: "json",
    success: function(data) {
        alert('success');
    },
    error: function(data) {
        alert('error');
    },
    complete: function(xhr, data) {
        if (xhr.status != 0)
             alert('success');
        else
             alert('fail');
    }
})

#2


9  

With your configuration jQuery uses jsonp to transport the data. This works by dynamically inserting a script element and setting the URL to the specified value. The data returned by the server is then evaluated as JavaScript - usually calling the provided callback. If the server returns a 404, the contents is obviously no JavaScript and the callback is never called. Some browsers support error handlers on the script tag, which are called in these situations. Unfortunately IE doens't support this. The best way to detect an error is to rely on a timeout.

在配置中,jQuery使用jsonp传输数据。这可以通过动态插入脚本元素并将URL设置为指定的值来实现。然后,服务器返回的数据被作为JavaScript进行评估——通常调用所提供的回调。如果服务器返回404,那么内容显然不是JavaScript,也不会调用回调。有些浏览器支持脚本标记上的错误处理程序,在这些情况下会调用它们。不幸的是IE不支持这一点。检测错误的最佳方法是依赖超时。

In your case you should specify an additional timeout option, which causes the error handler to be called if the callback wasn't called in time (which would be the case for a 404 response).

在这种情况下,您应该指定一个额外的超时选项,如果没有及时调用回调,就会调用错误处理程序(这是404响应的情况)。

$.ajax({
  url: 'http://my_url',
  timeout: 2000, // 2 seconds timeout
  dataType: "json",
  success: function(data){
    alert('success');
  },
  error: function(data){
    alert('error');
  },
  complete: function(data) {
    alert('complete')
  }
});

#3


4  

If you want to handle errors when accessing the Twitter API with Javascript and jsonp you need to include the parameter suppress_response_codes in your request. This makes all responses from the Twitter API respond with a 200 OK response and include a error. Then you need to check if the response includes the error parameter or not.

如果您希望在使用Javascript和jsonp访问Twitter API时处理错误,那么需要在请求中包含参数suppress_response_codes。这使得所有来自Twitter API的响应都以200 OK响应,并包含一个错误。然后您需要检查响应是否包含错误参数。

$.ajax({
  url: "https://api.twitter.com/1/users/show.json",
  dataType: 'jsonp',
  jsonp: "callback",
  data: {
    screen_name: "simongate1337",
    suppress_response_codes: true // <- Important part
  },
  success: function(data) {
    if(data.error) {
      console.log("ERROR: "+data.error);
    } else {
      console.log("Success, got user " + data.screen_name);
    }
  }
});

#4


3  

Use the statusCode-Option

使用statusCode-Option

$.ajax({
    url: 'http://my_url',
    dataType: "json",
    statusCode: {
        404:function(){
            alert("I could not find the informations you requested.");
        }
    } 
    success: function(data){
      alert('success');
    },
    error: function(data){
      alert('error');
    },
    complete: function(data) {
      alert('complete')
    }})

#5


2  

Do not you think that the problem is not with the dataType but with cross-domain requests that you are not allowed to make?

您不认为问题不在于数据类型,而在于不允许进行跨域请求吗?

The code below works as expected when you request data from the same domain and does not when you are making cross-domain requests:

当您请求来自同一域的数据时,下面的代码可以正常工作,而当您进行跨域请求时则不能:

function handle404(xhr){
    alert('404 not found');
}

function handleError(xhr, status, exc) {
     // 0 for cross-domain requests in FF and security exception in IE 
    alert(xhr.status);
    switch (xhr.status) {
        case 404:
            handle404(xhr);
            break;
    }
}

function dumbRequest() {
    var url = 'http://twitter.com/status/user_timeline/jksqdlmjmsd.json?count=3&callback=jsonp1269278524295&_=1269278536697';
    url = 'http://twitter.com/';    
    url = '/mydata.json';    
//    url = 'mydata.json';    
    $.ajax(
        {url: url,
         dataType: 'json',
         error: handleError}
    );
}

#6


1  

Is it simply because the dataType is set to "json"? If so, try changing it to text and evaluate the JSON yourself:

仅仅是因为数据类型被设置为“json”吗?如果是的话,试着把它改成文本并自己评估JSON:

$.ajax({
    url: 'http://twitter.com/status/user_timeline/jksqdlmjmsd.json?count=3&callback=jsonp1269278524295&_=1269278536697',
    dataType: 'text',
    success: function(data, status, xmlHttp) {
        try {
            data = eval('(' + data + ')');
            alert('success');
        } catch (e) {
            alert('json parse error');
        }
    },
    error: function(xmlHttp, status, error) {
        alert('error');
    },
    complete: function(xmlHttp, status) {
        alert('complete');
    }
});

#7


1  

Are you aware that even though the HTTP status is 404, the actual body is valid JSON? For instance, this link has the following JSON:

您是否知道,即使HTTP状态是404,实际的主体还是有效的JSON?例如,这个链接有以下JSON:

jsonp1269278524295({"request":"/status/user_timeline/jksqdlmjmsd.json?count=3&callback=jsonp1269278524295&_=1269278536697","error":"Not found"})

jsonp1269278524295({:“请求/地位/ user_timeline / jksqdlmjmsd.json吗?数= 3回调= jsonp1269278524295&_ = 1269278536697”、“错误”:“找不到”})

As such, you should check if your data has the error property within your normal callback function.

因此,您应该检查您的数据是否在常规回调函数中具有error属性。

UPDATE: apparently, even though the actual content of the page is valid JSON, the browser (I checked in Firefox) is not executing it, most likely because it is a 404. Because jQuery has to add a script element (because of the cross-domain issue), its JSONP wrapper is never called, and as a consequence, neither are your callbacks.

更新:显然,即使页面的实际内容是有效的JSON,浏览器(我在Firefox中检查过)也不会执行它,很可能是因为它是一个404。因为jQuery必须添加一个脚本元素(因为跨域问题),所以不会调用它的JSONP包装器,因此也不会调用回调。

So, in short, I don't think there is a way to deal with this without manually adding that script element and checking if your pre-defined callback function has been called afterwards.

因此,简而言之,我认为如果不手工添加那个脚本元素并检查您的预定义回调函数是否在之后被调用,就没有办法处理这个问题。

#8


1  

Just faced the same issue, and saw another question mentioned that jQuery-JSONP (jQuery Plugin) supports catching 404 errors or as they describe: "error recovery in case of network failure or ill-formed JSON responses"

只是遇到了同样的问题,看到另一个问题,即jQuery- jsonp (jQuery插件)支持捕获404错误,或者像他们描述的那样:“在网络故障或不良的JSON响应时进行错误恢复”

And it works perfect :)

而且效果完美:)

Here is my (simplified) code for fetching details about a YouTube video via JSONP:

下面是我通过JSONP获取YouTube视频细节的简化代码:

$.jsonp(
{
    url: "https://gdata.youtube.com/feeds/api/videos/ee925OTFBCA",
    callbackParameter: "callback",
    data: 
    {
        alt: "jsonc-in-script",
        v: "2"
    },
    success: function(json, textStatus) 
    { 
        console.log("WEEEEEEEE!"); 
    },
    error: function(xOptions, textStatus) 
    {
        console.error(arguments);
    }
});

#9


0  

Here's how I deal with this. I check the returned data for errors before trying to use it. What is shown below is just a sample that you could extend to more closely match your requirements. This also considers session time outs and other scenarios...

我是这样处理的。在尝试使用之前,我检查返回的数据是否有错误。下面显示的只是一个示例,您可以将其扩展到更接近您的需求。这也考虑了会话超时和其他场景…

My initial call:

我的初始调用:

  $.ajax({ type: 'POST', 
    url: '../doSomething',
    data: 'my data',
    success: function(data) {
      if (HasErrors(data)) return;
      var info = eval('(' + data + ')');
      // do what you want with the info object
    },
    error: function(xmlHttpRequest) {
      ReportFailure(xmlHttpRequest);
    }
  });

And the two helper functions:

以及两个辅助功能:

function HasErrors(data) {
  if (data.search(/login\.aspx/i) != -1) {
    // timed out and being redirected to login page!
    top.location.href = '../login.aspx';
    return true;
  }
  if (data.search(/Internal Server Error/) != -1) {
    ShowStatusFailed('Server Error.');
    return true;
  }
  if (data.search(/Error.aspx/) != -1) {
    // being redirected to site error reporting page...
    ShowStatusFailed('Server Error. Please try again.');
    return true;
  }
  return false;
}

and

function ReportFailure(msg) {
  var text;
  if (typeof msg == 'string') {
    text = msg;
  }
  else if (typeof msg.statusText == 'string') {
    if (msg.status == 200) {
      text = msg.responseText;
    }
    else {
      text = '(' + msg.status + ') ' + msg.statusText + ': ';
      // use the Title from the error response if possible
      var matches = msg.responseText.match(/\<title\>(.*?)\<\/title\>/i);
      if (matches != null)
      { text = text + matches[1]; }
      else
      { text = text + msg.responseText; }
    }
  }
  // do something in your page to show the "text" error message
  $('#statusDisplay')
    .html('<span class="ui-icon ui-icon-alert"></span>' + text)
    .addClass('StatusError');
}

#10


0  

Following solution is working fine for me :)

下面的解决方案对我来说没问题:)

$.ajax({
    url: 'http://my_url',
    dataType: "json",
    success: function(data){
      alert('success');
    },
    error: function(data){
      alert('error');
    },complete: function(xhr, data) {
        if(data==="parsererror"){
             alert('404');
        }
    } 
});

#1


19  

$.ajax({
    url: 'http://twitter.com/status/user_timeline/jksqdlmjmsd.json?count=3&callback=jsonp1269278524295&_=1269278536697',
    dataType: "json",
    success: function(data) {
        alert('success');
    },
    error: function(data) {
        alert('error');
    },
    complete: function(xhr, data) {
        if (xhr.status != 0)
             alert('success');
        else
             alert('fail');
    }
})

#2


9  

With your configuration jQuery uses jsonp to transport the data. This works by dynamically inserting a script element and setting the URL to the specified value. The data returned by the server is then evaluated as JavaScript - usually calling the provided callback. If the server returns a 404, the contents is obviously no JavaScript and the callback is never called. Some browsers support error handlers on the script tag, which are called in these situations. Unfortunately IE doens't support this. The best way to detect an error is to rely on a timeout.

在配置中,jQuery使用jsonp传输数据。这可以通过动态插入脚本元素并将URL设置为指定的值来实现。然后,服务器返回的数据被作为JavaScript进行评估——通常调用所提供的回调。如果服务器返回404,那么内容显然不是JavaScript,也不会调用回调。有些浏览器支持脚本标记上的错误处理程序,在这些情况下会调用它们。不幸的是IE不支持这一点。检测错误的最佳方法是依赖超时。

In your case you should specify an additional timeout option, which causes the error handler to be called if the callback wasn't called in time (which would be the case for a 404 response).

在这种情况下,您应该指定一个额外的超时选项,如果没有及时调用回调,就会调用错误处理程序(这是404响应的情况)。

$.ajax({
  url: 'http://my_url',
  timeout: 2000, // 2 seconds timeout
  dataType: "json",
  success: function(data){
    alert('success');
  },
  error: function(data){
    alert('error');
  },
  complete: function(data) {
    alert('complete')
  }
});

#3


4  

If you want to handle errors when accessing the Twitter API with Javascript and jsonp you need to include the parameter suppress_response_codes in your request. This makes all responses from the Twitter API respond with a 200 OK response and include a error. Then you need to check if the response includes the error parameter or not.

如果您希望在使用Javascript和jsonp访问Twitter API时处理错误,那么需要在请求中包含参数suppress_response_codes。这使得所有来自Twitter API的响应都以200 OK响应,并包含一个错误。然后您需要检查响应是否包含错误参数。

$.ajax({
  url: "https://api.twitter.com/1/users/show.json",
  dataType: 'jsonp',
  jsonp: "callback",
  data: {
    screen_name: "simongate1337",
    suppress_response_codes: true // <- Important part
  },
  success: function(data) {
    if(data.error) {
      console.log("ERROR: "+data.error);
    } else {
      console.log("Success, got user " + data.screen_name);
    }
  }
});

#4


3  

Use the statusCode-Option

使用statusCode-Option

$.ajax({
    url: 'http://my_url',
    dataType: "json",
    statusCode: {
        404:function(){
            alert("I could not find the informations you requested.");
        }
    } 
    success: function(data){
      alert('success');
    },
    error: function(data){
      alert('error');
    },
    complete: function(data) {
      alert('complete')
    }})

#5


2  

Do not you think that the problem is not with the dataType but with cross-domain requests that you are not allowed to make?

您不认为问题不在于数据类型,而在于不允许进行跨域请求吗?

The code below works as expected when you request data from the same domain and does not when you are making cross-domain requests:

当您请求来自同一域的数据时,下面的代码可以正常工作,而当您进行跨域请求时则不能:

function handle404(xhr){
    alert('404 not found');
}

function handleError(xhr, status, exc) {
     // 0 for cross-domain requests in FF and security exception in IE 
    alert(xhr.status);
    switch (xhr.status) {
        case 404:
            handle404(xhr);
            break;
    }
}

function dumbRequest() {
    var url = 'http://twitter.com/status/user_timeline/jksqdlmjmsd.json?count=3&callback=jsonp1269278524295&_=1269278536697';
    url = 'http://twitter.com/';    
    url = '/mydata.json';    
//    url = 'mydata.json';    
    $.ajax(
        {url: url,
         dataType: 'json',
         error: handleError}
    );
}

#6


1  

Is it simply because the dataType is set to "json"? If so, try changing it to text and evaluate the JSON yourself:

仅仅是因为数据类型被设置为“json”吗?如果是的话,试着把它改成文本并自己评估JSON:

$.ajax({
    url: 'http://twitter.com/status/user_timeline/jksqdlmjmsd.json?count=3&callback=jsonp1269278524295&_=1269278536697',
    dataType: 'text',
    success: function(data, status, xmlHttp) {
        try {
            data = eval('(' + data + ')');
            alert('success');
        } catch (e) {
            alert('json parse error');
        }
    },
    error: function(xmlHttp, status, error) {
        alert('error');
    },
    complete: function(xmlHttp, status) {
        alert('complete');
    }
});

#7


1  

Are you aware that even though the HTTP status is 404, the actual body is valid JSON? For instance, this link has the following JSON:

您是否知道,即使HTTP状态是404,实际的主体还是有效的JSON?例如,这个链接有以下JSON:

jsonp1269278524295({"request":"/status/user_timeline/jksqdlmjmsd.json?count=3&callback=jsonp1269278524295&_=1269278536697","error":"Not found"})

jsonp1269278524295({:“请求/地位/ user_timeline / jksqdlmjmsd.json吗?数= 3回调= jsonp1269278524295&_ = 1269278536697”、“错误”:“找不到”})

As such, you should check if your data has the error property within your normal callback function.

因此,您应该检查您的数据是否在常规回调函数中具有error属性。

UPDATE: apparently, even though the actual content of the page is valid JSON, the browser (I checked in Firefox) is not executing it, most likely because it is a 404. Because jQuery has to add a script element (because of the cross-domain issue), its JSONP wrapper is never called, and as a consequence, neither are your callbacks.

更新:显然,即使页面的实际内容是有效的JSON,浏览器(我在Firefox中检查过)也不会执行它,很可能是因为它是一个404。因为jQuery必须添加一个脚本元素(因为跨域问题),所以不会调用它的JSONP包装器,因此也不会调用回调。

So, in short, I don't think there is a way to deal with this without manually adding that script element and checking if your pre-defined callback function has been called afterwards.

因此,简而言之,我认为如果不手工添加那个脚本元素并检查您的预定义回调函数是否在之后被调用,就没有办法处理这个问题。

#8


1  

Just faced the same issue, and saw another question mentioned that jQuery-JSONP (jQuery Plugin) supports catching 404 errors or as they describe: "error recovery in case of network failure or ill-formed JSON responses"

只是遇到了同样的问题,看到另一个问题,即jQuery- jsonp (jQuery插件)支持捕获404错误,或者像他们描述的那样:“在网络故障或不良的JSON响应时进行错误恢复”

And it works perfect :)

而且效果完美:)

Here is my (simplified) code for fetching details about a YouTube video via JSONP:

下面是我通过JSONP获取YouTube视频细节的简化代码:

$.jsonp(
{
    url: "https://gdata.youtube.com/feeds/api/videos/ee925OTFBCA",
    callbackParameter: "callback",
    data: 
    {
        alt: "jsonc-in-script",
        v: "2"
    },
    success: function(json, textStatus) 
    { 
        console.log("WEEEEEEEE!"); 
    },
    error: function(xOptions, textStatus) 
    {
        console.error(arguments);
    }
});

#9


0  

Here's how I deal with this. I check the returned data for errors before trying to use it. What is shown below is just a sample that you could extend to more closely match your requirements. This also considers session time outs and other scenarios...

我是这样处理的。在尝试使用之前,我检查返回的数据是否有错误。下面显示的只是一个示例,您可以将其扩展到更接近您的需求。这也考虑了会话超时和其他场景…

My initial call:

我的初始调用:

  $.ajax({ type: 'POST', 
    url: '../doSomething',
    data: 'my data',
    success: function(data) {
      if (HasErrors(data)) return;
      var info = eval('(' + data + ')');
      // do what you want with the info object
    },
    error: function(xmlHttpRequest) {
      ReportFailure(xmlHttpRequest);
    }
  });

And the two helper functions:

以及两个辅助功能:

function HasErrors(data) {
  if (data.search(/login\.aspx/i) != -1) {
    // timed out and being redirected to login page!
    top.location.href = '../login.aspx';
    return true;
  }
  if (data.search(/Internal Server Error/) != -1) {
    ShowStatusFailed('Server Error.');
    return true;
  }
  if (data.search(/Error.aspx/) != -1) {
    // being redirected to site error reporting page...
    ShowStatusFailed('Server Error. Please try again.');
    return true;
  }
  return false;
}

and

function ReportFailure(msg) {
  var text;
  if (typeof msg == 'string') {
    text = msg;
  }
  else if (typeof msg.statusText == 'string') {
    if (msg.status == 200) {
      text = msg.responseText;
    }
    else {
      text = '(' + msg.status + ') ' + msg.statusText + ': ';
      // use the Title from the error response if possible
      var matches = msg.responseText.match(/\<title\>(.*?)\<\/title\>/i);
      if (matches != null)
      { text = text + matches[1]; }
      else
      { text = text + msg.responseText; }
    }
  }
  // do something in your page to show the "text" error message
  $('#statusDisplay')
    .html('<span class="ui-icon ui-icon-alert"></span>' + text)
    .addClass('StatusError');
}

#10


0  

Following solution is working fine for me :)

下面的解决方案对我来说没问题:)

$.ajax({
    url: 'http://my_url',
    dataType: "json",
    success: function(data){
      alert('success');
    },
    error: function(data){
      alert('error');
    },complete: function(xhr, data) {
        if(data==="parsererror"){
             alert('404');
        }
    } 
});