13.2 处理 Ajax 错误

在应用中引入任何形式的网络交互,都会同时带来某种不确定因素。用户的连接可能会在中途停止,偶尔的服务器问题可能会中断通信。鉴于这些问题都会影响到通信的可靠性,我们必须时刻做好最坏的打算,甚至要做好处理错误的准备。

$.ajax()函数可以接收一个名为error的回调函数,这个函数可以处理上述这些问题。在这个回调函数中,我们应该向用户提供某种形式的反馈,告知用户发生了错误,参见代码清单13-5。

代码清单13-5

  1. $(document).ready(function() {
  2. var $ajaxForm = $('#ajax-form'),
  3. $response = $('#response'),
  4. noresults = 'There were no search results.',
  5. failed = 'Sorry, but the request could not ' + 'reach its destination. Try again later.';
  6.  
  7. $ajaxForm.on('submit', function(event) {
  8. event.preventDefault();
  9.  
  10. $.ajax({
  11. url: 'http://book.learningjquery.com/api/',
  12. dataType: 'jsonp',
  13. data: {
  14. title: $('#title').val()
  15. },
  16. success: response,
  17. error: function() {
  18. $response.html(failed);
  19. }
  20. });
  21. });
  22. });

触发这个错误回调函数的情况有很多种。下面列出了其中的一些错误。

  • 服务器返回了错误状态码,例如403 Forbidden、404 Not Found或500 Internet Server Error。

  • 服务器返回了间接的状态码,例如301 Moved Permanently。状态码为304 Not Modified的异常不会触发错误,因为浏览器可以正确地处理这种情况。

  • 服务器返回的数据不能按照指定方式正确解析(例如,在dataType指定为json时,返回的不是有效的JSON数据)。

  • XMLHttpRequest对象调用了.abort()方法。

检测这些情况并对它们做出响应是提供最佳用户体验的关键。第6章曾讨论过,如果服务器返回错误,那么通过传递给错误回调函数的jqXHR对象的.status属性,可以检测到该错误。换句话说,使用jaXHR.status的值可以对不同的错误给出不同的响应。

然而,服务器错误只有你检测到它的时候才有用。有些错误可以立即检测到,而有些情况则会导致请求到最终错误响应之间产生很长的时间延迟。

在没有既定的服务器端超时机制的情况下,我们可以在客户端强制设定请求的超时。通过给timeout选项传递一个以毫秒表示的时间值,就相当于告诉$.ajax():如果响应在多长时间内没有返回,那么就调用它自己的.abort()方法,参见代码清单13-6。

代码清单13-6

  1. $.ajax({
  2. url: 'http://book.learningjquery.com/api/',
  3. dataType: 'jsonp',
  4. data: {
  5. title: $('#title').val()
  6. },
  7. timeout: 15000,
  8. success: response,
  9. error: function() {
  10. $response.html(failed);
  11. }
  12. });

设置了超时时间后,就可以确保在15秒内,要么正常加载数据,要么用户能看到一条错误消息。