2011-10-07 17 views
13

tôi đã xây dựng một trường hợp thử nghiệm của một cuộc gọi ajax (jQuery 1.6.2) trông giống như:xử lý lỗi jQuery.ajax cho cross-domain jsonp gọi

jQuery(document).ready(function($) { 
    var test = function(x) { 
     $.ajax({ 
      url: 'http://www.someotherdomain.com/test.php', 
      data: { x: x }, 
      dataType: 'jsonp', 
      crossDomain: true, 
      success: function(data) { 
       console.log(data.name); 
      }, 
      error: function() { 
       x++; 
       test(x); 
      } 
     }); 
    }; 
    test(1); 
}); 

Và tương ứng test.php tập tin trông giống như:

if (5 > $_GET[ 'x' ]) { 
    header('HTTP/1.1 503 Service Temporarily Unavailable'); die(); 
} else { 
    header('content-type: application/x-javascript'); 
    echo $_GET[ 'callback' ] . '({"name":"Morgan"})'; 
} 

Mặc dù jQuery documentation cho biết rằng trình xử lý lỗi cho cuộc gọi jsonp không bao giờ được kích hoạt, tập lệnh này hoạt động giống như tôi dự định. Nó làm cho bốn cuộc gọi "không thành công" thành test.php trả về 503 lỗi, và sau đó test() gọi đệ quy tăng x cho đến khi cuộc gọi ajax là "thành công" và dữ liệu được xuất ra bàn điều khiển.

Vì vậy, trường hợp thử nghiệm của tôi trên các công trình, nhưng mã thực tế của tôi không làm việc, mà trông giống như sau:

jQuery(document).ready(function($) { 
    var completed = 0; 
    var fiftystates; // assume an array of state objects 
    var updateState = function(index, state) { 
     var d = index % 5; // for subdomains sub0, sub1, sub2, sub3, sub4 
     $.ajax({ 
      url: 'http://sub' + d + '.mydomain.com/update_state.php', 
      data: { state: state.id }, 
      dataType: 'jsonp', 
      crossDomain: true, 
      success: function() { 
       completed++; 
       var complete_percent = completed/fiftystates.length * 100; 
       $('#progressbar').progressbar('value', completed_percent); 
      }, 
      error: function() { 
       updateState(index, state); 
      } 
     }); // end ajax 
    }; // end updateState 
    $(fiftystates).each(updateState); 
}; 

Như bạn có thể thấy, đây vòng qua 5 tiểu lĩnh vực khác nhau mà trên thực tế chỉ là các gương của cùng một miền, nhưng vì update_state.php có thể mất đến 30 giây để hoàn thành, quá trình này mất 25 phút xuống dưới ba phút. Vấn đề là các máy chủ đập gây ra một số yêu cầu ajax thất bại với một lỗi 503. Trong trường hợp thử nghiệm của tôi, điều này đã được xử lý mà không có vấn đề gì nhưng trong ví dụ thứ hai của tôi, trình xử lý lỗi không bao giờ có vẻ được gọi.

Tôi không thể hiểu tại sao trường hợp thử nghiệm hoạt động như tôi mong đợi và trường hợp thứ hai không hoạt động. Bất kỳ ý tưởng?

+0

cố gắng thay đổi lên đến jQuery 1.6. 4 với cùng một kết quả – morphatic

+0

nó có thể được rằng bằng cách sử dụng php 'header()' để trả lại 503 hành vi khác với một "thực tế" 503? Tôi đã kiểm tra các tiêu đề HTTP của cả hai trường hợp và chúng trông giống hệt với tôi ... – morphatic

+0

Trong ví dụ đầu tiên của bạn, bạn tăng x mỗi lần (x ++;) trong trình xử lý lỗi. Trong lần thứ hai, bạn không tăng chỉ số ++; đó là sự khác biệt rõ ràng duy nhất tôi có thể thấy. – Kato

Trả lời

2

Trong trường hợp thử nghiệm của bạn, bạn thay đổi giá trị x für mỗi cuộc gọi ...

Trong mã khác bạn đang gửi cùng một giá trị chỉ mục. Mà sẽ trả về kết quả tương tự, thay vì "xoay" thông qua các tên miền phụ ...

error: function() { 
     index++; 
     updateState(index, state); 
    } 
+1

Tham số chỉ mục được tự động tăng lên bởi hàm jQuery.each() gọi bên cạnh dòng cuối cùng. Ý nghĩ tốt, nhưng tôi không nghĩ đó là vấn đề. – morphatic

+0

Tôi hiểu rằng chỉ mục được thay đổi bởi cuộc gọi hàm .each(). Tuy nhiên, điều đó không ảnh hưởng đến chỉ mục được gọi trong trường hợp lỗi. Đối với mỗi trạng thái trong mảng của bạn, bạn gọi hàm, gọi chính nó trong trường hợp có lỗi ... – blindfold

2

Nếu tình cờ bạn đang sử dụng IE để kiểm tra các trường hợp đầu tiên và có thể là FF hoặc Chrome để kiểm tra trường hợp thứ hai thì đó có thể là nguyên nhân. Lỗi và gọi lại toàn cầu không được gọi cho các loại JSON/JSONP miền chéo như được tài liệu hóa bởi hàm jQuery.ajax. Tuy nhiên, tôi đã nhận thấy rằng họ vẫn nhận được gọi là trong IE và tôi nghĩ rằng điều này có cái gì để làm với jQuery bằng cách sử dụng IE XMLHttpRequest để làm các cuộc gọi.

Có vẻ ai đó đã ân cần tạo một plugin để xử lý lỗi với yêu cầu JSONP sẵn ở đây: http://code.google.com/p/jquery-jsonp/

3

nó phải ở định dạng như thế này:

$.ajax({ 
    type: "POST", 
    url: 'http://servername/WebService.svc/GetData?callback=?', 
    dataType: 'jsonp', 
    success: function (data) { 
     //do stuff 
    }, 
    error: function (msg, b, c) { 
    //alert error 
    } 
}); 
+0

JSONP không thể được sử dụng để thực hiện các yêu cầu POST trên các tên miền. jQuery sẽ tự động thay đổi điều này thành yêu cầu GET. – cesarislaw

+2

kiểm tra trang web jquery "Lưu ý: Trình xử lý này không được gọi cho tập lệnh tên miền chéo và yêu cầu JSONP nhiều miền." – shereifhawary

0
function AjaxRequest(url, params){ 

    return $.ajax({ 
     url:   url, 
     data:   params, 
     dataType:  'jsonp', 

     /* Very important */ 
     contentType: 'application/json', 
    }); 
} 

var test = function(x) { 

    AjaxFeed('http://servername/WebService.svc/GetData', {x: x}) 

    /* Everything worked okay. Hooray */ 
    .done(function(data){ 

     console.log(data); 
    }) 

    /* Oops */ 
    .fail(function(jqXHR, sStatus, oError) { 

     console.log(arguments); 
    }); 
} 

jQuery(window).load(function() { 

    test('test'); 
}