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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/2493974/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-23 00:38:22  来源:igfitidea点击:

How to callback a function on 404 in JSON ajax request with jQuery?

javascriptajaxjqueryhttp-status-code-404

提问by shingara

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 时,没有使用回调,即使是完整的回调。经过研究,这是因为我的dataType是'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&_=1269278536697it's with this URL I have my problem.

编辑:complete回调不叫是回报404。如果你想要一个URL机智404您可以拨打:http://twitter.com/status/user_timeline/jksqdlmjmsd.json?count=3&callback=jsonp1269278524295&_=1269278536697它与此URL 我有我的问题。

回答by Dustin Laine

$.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');
    }
})

回答by Fabian Jakobs

With your configuration jQuery uses jsonpto 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 timeoutoption, 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).

在您的情况下,您应该指定一个附加timeout选项,如果未及时调用回调(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')
  }
});

回答by Simon Gate

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

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

$.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);
    }
  }
});

回答by Grim

Use the statusCode-Option

使用statusCode-Option

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

回答by newtover

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}
    );
}

回答by janmoesen

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

您是否知道即使 HTTP 状态为 404,实际正文也是有效的 JSON?例如,此链接具有以下 JSON:

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

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

As such, you should check if your data has the errorproperty 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 scriptelement (because of the cross-domain issue), its JSONP wrapper is never called, and as a consequence, neither are your callbacks.

更新:显然,即使页面的实际内容是有效的 JSON,浏览器(我在 Firefox 中检查过)也没有执行它,很可能是因为它是 404。因为 jQuery 必须添加一个script元素(因为交叉域问题),它的 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.

因此,简而言之,我认为没有办法在不手动添加该脚本元素并检查您的预定义回调函数之后是否已调用的情况下处理此问题。

回答by Matt Huggins

Is it simply because the dataTypeis set to "json"? If so, try changing it to textand evaluate the JSON yourself:

仅仅是因为dataType设置为“json”吗?如果是这样,请尝试将其更改为text并自己评估 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');
    }
});

回答by Mark

Just faced the same issue, and saw another questionmentioned 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);
    }
});

回答by Awan

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');
        }
    } 
});

回答by Glen Little

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');
}