【问题标题】:How to callback a function on 404 in JSON ajax request with jQuery?如何使用 jQuery 在 JSON ajax 请求中回调 404 上的函数?
【发布时间】:2011-01-30 10:34:35
【问题描述】:

我想用 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')
    }})

此代码运行良好,但是当我的 url 向我发送 HTTP 代码 404 时,没有使用任何回调,甚至是完整的回调。 经过研究,这是因为我的dataType是'json'所以404返回是HTML并且JSON解析失败。所以没有回调。

您有解决方案在引发 404 时调用回调函数吗?

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

【问题讨论】:

    标签: javascript ajax jquery http-status-code-404


    【解决方案1】:
    $.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');
        }
    })
    

    【讨论】:

    • 你不是说:“完成:函数(状态,文本){”
    • 我也尝试过,但完成回调它也没有调用 :( 我用这个解决方案更新我的问题并进行更多解释
    • 是一样的。如果您只是在完成功能时发出警报,则不会调用。
    • 嗯?这是给我的。我复制了您的代码并且它有效,我只是扩展以显示您将如何处理。使用 Firebug 并查看您的请求/响应。某处可能出现 JS 错误。
    • 我正在使用 codeigniter,它只是忽略了所有回调,网络检查器显示 404 错误。
    【解决方案2】:

    通过您的配置,jQuery 使用jsonp 来传输数据。这通过动态插入脚本元素并将 URL 设置为指定值来工作。然后服务器返回的数据被评估为 JavaScript - 通常调用提供的回调。如果服务器返回 404,则内容显然不是 JavaScript,并且永远不会调用回调。一些浏览器支持脚本标签上的错误处理程序,在这些情况下会调用这些错误处理程序。不幸的是 IE 不支持这个。检测错误的最佳方法是依靠超时。

    在您的情况下,您应该指定一个额外的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')
      }
    });
    

    【讨论】:

    • 超时未解决解决方案。通过后什么都不叫:(
    • 这里一样,我的只是每次都触发错误,虽然它获取了数据。
    • 不确定这个答案在 -1 一直在做什么。
    【解决方案3】:

    使用statusCode-选项

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

    【讨论】:

      【解决方案4】:

      如果您想在使用 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);
          }
        }
      });
      

      【讨论】:

        【解决方案5】:

        你不认为问题不在于 dataType 而是在于不允许你发出的跨域请求吗?

        当您从同一个域请求数据时,下面的代码按预期工作,而当您发出跨域请求时则不能:

        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】:

          仅仅是因为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');
              }
          });
          

          【讨论】:

          【解决方案7】:

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

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

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

          更新:显然,即使页面的实际内容是有效的 JSON,浏览器(我在 Firefox 中检查)也没有执行它,很可能是因为它是 404。因为 jQuery 有添加 script 元素(由于跨域问题),它的 JSONP 包装器永远不会被调用,因此,您的回调也不会。

          所以,简而言之,如果不手动添加该脚本元素并检查您的预定义回调函数是否在之后被调用,我认为没有办法解决这个问题。

          【讨论】:

            【解决方案8】:

            刚遇到同样的问题,看到 another question 提到 jQuery-JSONP (jQuery Plugin) 支持捕获 404 错误或如他们所述:“在网络故障或格式错误的 JSON 响应的情况下进行错误恢复”

            而且效果很好:)

            这是我的(简化的)代码,用于通过 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);
                }
            });
            

            【讨论】:

            • 这是一个很好的解决实际问题的方法。很遗憾,图书馆似乎已经停止开发。现代版本的 jQuery 是否有类似的解决方案?
            【解决方案9】:

            我是这样处理的。在尝试使用它之前,我会检查返回的数据是否有错误。下面显示的只是一个示例,您可以扩展它以更符合您的要求。这还考虑了会话超时和其他情况...

            我最初的电话:

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

            还有两个辅助函数:

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

            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】:

              以下解决方案对我来说效果很好:)

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

              【讨论】:

                猜你喜欢
                • 2013-08-01
                • 2011-07-25
                • 2018-09-25
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                • 2021-08-13
                • 1970-01-01
                • 2013-09-29
                相关资源
                最近更新 更多