简体   繁体   English

如何根据服务器响应触发jquery.ajax()错误回调,而不是HTTP 500?

[英]How to trigger jquery.ajax() error callback based on server response, not HTTP 500?

By using jquery ajax function, I can do something like: 通过使用jquery ajax函数,我可以做类似的事情:

$.ajax({

  url: url,
  type: 'GET',
  async: true,
  dataType: 'json',
  data: data,

 success: function(data) {

     //Handle server response here

  },

 error: function(xhr, status, error){

    //Handle failure here

 }

});

I got two questions to ask based on above code: 根据以上代码,我有两个问题要问:

  1. When will the jquery.ajax() error callback be called?? 什么时候会调用jquery.ajax() error回调?

  2. What if server response to me a json object with string message " There is an error ". 如果服务器使用字符串消息“ 有错误 ”向我回复json对象怎么办? Which means the request is still send successfully, but I got server response {message: "There is an error"} . 这意味着请求仍然成功发送,但我得到了服务器响应{message: "There is an error"}

I think no matter what string value server is responsed, if client got server's response, the jquery.ajax() success callback will be triggered anyway. 我认为无论服务器响应什么字符串值,如果客户端得到服务器的响应,无论如何都会触发jquery.ajax() success回调。

I'd like to ask if server specifically returns to me a JSON object with string value like {message: 'There is an error'} , could server do something so that this response could be handled in jquery.ajax() error callback instead of success callback? 我想询问服务器是否专门向我返回一个字符串值为{message: 'There is an error'}的JSON对象,服务器可以执行某些操作以便可以在jquery.ajax() error回调中处理此响应success回调?

The error callback will be executed when the response from the server is not going to be what you were expecting. 当服务器的响应不符合您的预期时,将执行错误回调。 So for example in this situations it: 例如,在这种情况下,它:

  • HTTP 404/500 or any other HTTP error message has been received 已收到HTTP 404/500或任何其他HTTP错误消息
  • data of incorrect type was received (ie you have expected JSON, you have received something else). 收到了不正确类型的数据(即您已经预期JSON,您已收到其他内容)。

In your situation the data is correct (it's a JSON message). 在您的情况下,数据是正确的(这是一个JSON消息)。 If you want to manually trigger the error callback based on the value of the received data you can do so quite simple. 如果要根据接收数据的值手动触发错误回调,则可以非常简单地完成。 Just change the anonymous callback for error to named function. 只需将错误的匿名回调更改为命名函数即可。

function handleError(xhr, status, error){

    //Handle failure here

 }

$.ajax({

  url: url,
  type: 'GET',
  async: true,
  dataType: 'json',
  data: data,

 success: function(data) {
     if (whatever) {
         handleError(xhr, status, ''); // manually trigger callback
     }
     //Handle server response here

  },

 error: handleError
});

We presume the server is sending JSON, and in case of a successful request we'll get something like this: 我们假设服务器正在发送JSON,如果请求成功,我们将得到如下内容:

{
    success: true,
    data: {
        name: 'Foo'
    }
}

... and on failure: ......并且失败了:

{
    success: false,
    error: 'Something bad happened.'
}

Then we simply filter the response with a $.Deferred : 然后我们只需使用$ .Deferred过滤响应:

$.get('http://localhost/api').then(function(res) {
    var filter = $.Deferred();

    if (res.success) {
        filter.resolve(res.data);
    } else {
        filter.reject(res.error);
    }

    return filter.promise();
}).done(function(data) {
    console.log('Name:',  data.name); // Outputs: Foo
}).fail(function(error) {
    console.log('Error:', error); // Outputs: Something bad happened.
})

The error callback is for when the Ajax round-trip could not be completed successfully, not something based on your server logic. 错误回调是为了无法成功完成Ajax往返,而不是基于您的服务器逻辑。 It would be your responsibility to check for what you consider to be a successful response inside the success callback. 您有责任在成功回调中检查您认为成功响应的内容。 ie Add a single IF conditional that checks if the message = "There was an error." 即添加一个IF条件,检查消息是否“出错”。 and include your error logic there, otherwise do the success logic. 并在那里包含您的错误逻辑,否则执行成功逻辑。

An approach to do what you ask for would be to have the server return a 404 header when there is an error, then it would be handled by the error callback. 执行您要求的方法是让服务器在出现错误时返回404标头,然后由错误回调处理。 The problem with this approach is that you'd be hiding if there are actual errors, and you wouldn't be able to pass additional data with it. 这种方法的问题在于,如果存在实际错误,您将隐藏,并且您将无法使用它传递其他数据。

Simplest thing to do would be to restructure like so: 最简单的事情就是像这样重组:

function handleAjaxError function(xhr, status, error) {
    //Handle failure here
}

$.ajax({
  url: url,
  type: 'GET',
  async: true,
  dataType: 'json',
  data: data,

  success: function(data) {

     //Handle server response here
    if (data.message == 'There is an error')
    {
        handleAjaxError();
        return;
    }

    //... all is good....

  },
  error: handleAjaxError
});

One easy way to do this is to just use the jQuery always() function for your callback and then if you want to manually create an error just take advantage of Duck Typing! 一个简单的方法是只使用jQuery always()函数进行回调,然后如果你想手动创建错误就可以利用Duck Typing!

For example: 例如:

$.get(url, {"data": data}).always(function(result)
{
    if (typeof result.status !== "undefined" && result.status !== 200) // Status code 200 represents Success/OK
    {
        //handle error
        error = "Your error was " + result.status + " " + result.statusText;
    }
    else
    {
        //success
    }
});

The error section will always be run if there was a natural header error such as a 404 Not Found. 如果存在自然标头错误(例如404 Not Found),则始终会运行错误部分。 If you want to manually return an error, you can just emulate the XHR object normally passed with an error (eg in PHP): 如果要手动返回错误,可以模拟通常传递错误的XHR对象(例如在PHP中):

public function ServerSideAjaxResponse($data)
{
    if (!$data)
    {
        $response["status"] = 1001; //Make up your own error codes! Yippee! Fun!
        $response["statusText"] = "Error! You forgot to send the data!";
        echo json_encode($return);
        return;
    }
}

This original question was posted years ago, and perhaps there are better ways of handling this now. 这个原始问题是在几年前发布的,也许现在有更好的方法来处理这个问题。 Here's a suggestion to handle multiple types of errors , including the OP's question. 这是一个处理多种类型错误的建议,包括OP的问题。

Input type (error) example #1 输入类型(错误)示例#1

 function handleError (type){ type = type || "Connection Issue"; var value = "Error occurred: " + type; alert(value); } function checkIfError(response){ if (response == "DB_ERROR") { handleError("Server error"); throw new Error("JS died"); // optional, keep from running additional script } } var example = { success: function (response) { checkIfError(response); // check data if error msg // do stuff when proper data sent alert(response); }, error: handleError // connection error, call error msg }; test1 = example['error'](); 

Input type (success:error) example #2 输入类型(成功:错误)示例#2

 function handleError (type){ type = type || "Connection Issue"; var value = "Error occurred: " + type; alert(value); } function checkIfError(response){ if (response == "DB_ERROR") { handleError("Server error"); throw new Error("JS died"); // optional, keep from running additional script } } var example = { success: function (response) { checkIfError(response); // check data if error msg // do stuff when proper data sent alert(response); }, error: handleError // connection error, call error msg }; test2 = example['success']("DB_ERROR"); 

Input type (success) example #3 输入类型(成功)示例#3

 function handleError (type){ type = type || "Connection Issue"; var value = "Error occurred: " + type; alert(value); } function checkIfError(response){ if (response == "DB_ERROR") { handleError("Server error"); throw new Error("JS died"); // optional, keep from running additional script } } var example = { success: function (response) { checkIfError(response); // check data if error msg // do stuff when proper data sent alert(response); }, error: handleError // connection error, call error msg }; test3 = example['success']("Proper Response"); 

By using functions, if you have multiple calls in your scripts, you can simplify changes. 通过使用函数,如果脚本中有多个调用,则可以简化更改。

Have your PHP (or whatever server side code) return the response of "DB_ERROR" (or whatever you want) to trigger the error; 让你的PHP(或任何服务器端代码)返回“DB_ERROR” (或任何你想要的)的响应来触发错误; allows you to do different things depending on the error. 允许您根据错误执行不同的操作。

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

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