2011-06-24 47 views
16

Tôi đang sử dụng cuộc gọi JSONP ajax để tải một số nội dung từ một miền khác và tất cả nội dung này được thực thi nếu người dùng gây "di chuột qua" trên nút.Hủy bỏ yêu cầu ajax JSONP với jQuery

Tôi có thể ghi lại lệnh gọi $ .ajax() làm đối tượng xhr và sử dụng nó để hủy yêu cầu ajax mỗi khi người dùng gây ra "di chuột qua". Nhưng hàm gọi lại JSONP vẫn được gọi, và điều này gây ra một lỗi, và tôi nghĩ rằng nó là beacuse xhr.abort() phương pháp không ngăn chặn các chức năng gọi lại được gọi.

Tôi đã thử xung quanh cuộc gọi $ .ajax() với try {} catch (e) {}, nhưng sau khi tôi gọi phương thức xhr.abort(), lỗi vẫn tiếp tục.

Có cách nào để xử lý ngoại lệ đó không?

Trường hợp ngoại lệ nêu ra là như thế này (theo Firebug): jQuery16102234208755205157_1308941669256 không phải là một chức năng

Và cấu trúc nội bộ của ngoại lệ là như thế này: jQuery16102234208755205157_1308941669256 ({... dữ liệu json của tôi từ một tên miền khác nhau ....})

+0

bản sao có thể có của [Giết yêu cầu ajax bằng javascript sử dụng jquery.] (Http://stackoverflow.com/questions/446594/kill-ajax-requests-using-javascript-using-jquery) – Neal

+3

Tôi đoán đây không phải là trùng lặp, bởi vì câu hỏi này là về việc ngăn chặn một ngoại lệ sau khi phương thức jqxhr.abort() được gọi trên một yêu cầu ajax JSONP, không phải về cách tự dừng yêu cầu đó. –

+0

Câu trả lời cho câu hỏi này có thể được tìm thấy tại câu hỏi trùng lặp http: // stackoverflow.com/questions/9533848/aborting-jquery-jsonp-request-sẽ-ném-lỗi –

Trả lời

-2

Trong jQuery 1.5 tất cả các API Ajax có một đối tượng bao bọc xung quanh các đối tượng XHR gốc. Hãy xem tại địa chỉ:

http://api.jquery.com/jQuery.ajax/#jqXHR

jqxhr.abort(); // should be what you're looking for 
+2

Đây là những gì tôi đang sử dụng ngay bây giờ. Điều này hủy bỏ yêu cầu ajax. Nhưng yêu cầu ajax này sử dụng JSONP. Sau khi tôi sử dụng phương thức "abort()", một hàm javascript được jQuery tạo bên trong để xử lý phản hồi JSONP được gọi, nhưng phương thức hủy bỏ dường như loại bỏ định nghĩa hàm đó, hoặc một cái gì đó, bởi vì có một ngoại lệ mà tôi chưa có thể xử lý. –

+0

Bạn có thêm thông tin nào không? ví dụ trực tiếp, thông báo ngoại lệ? –

11

Câu trả lời cơ bản chỉ đơn giản là một trao here là: Bạn có thể không thực sự abort() một cuộc gọi JSONP. Vì vậy, câu hỏi thực sự là, làm thế nào để bạn tránh được cả những lời gọi lại không cần thiết và lỗi mà bạn đang gặp phải?

Bạn không thể sử dụng try...catch xung quanh cuộc gọi lại vì nó không đồng bộ; bạn cần phải nắm bắt nó từ cuối jQuery, và jQuery thường không xử lý các ngoại lệ được ném ra khỏi các cuộc gọi lại. Thay vào đó, những gì bạn muốn làm là sử dụng một mã định danh duy nhất cho mỗi cuộc gọi Ajax và, khi gọi lại thành công được gọi, hãy kiểm tra xem số nhận dạng đó có giống như khi bạn thực hiện cuộc gọi hay không . Dưới đây là một thực hiện dễ dàng:

var requestCount = 0; 
$.ajax(url, { 
    dataType: 'jsonp', 
    requestCount: ++requestCount, 
    success: function(response, code) { 
    if (requestCount !== this.requestCount) return; 
    // if we're still here, this is the latest request... 
    } 
}); 

Ở đây tôi đang lợi dụng thực tế là bất cứ điều gì bạn vượt qua để $.ajax được gắn vào đối tượng đó được sử dụng như this trong callback.

Thật tuyệt nếu jQuery thực hiện việc này cho tất cả chúng ta, tất nhiên rồi.

1

jsonpString ghi đè tên hàm gọi lại trong yêu cầu jsonp. Giá trị này sẽ được sử dụng thay vì 'gọi lại' trong 'callback =?' một phần của chuỗi truy vấn trong URL.

Vì vậy, {jsonp:'onJSONPLoad'} sẽ dẫn đến 'onJSONPLoad=?' được chuyển đến máy chủ. Kể từ jQuery 1.5, việc thiết lập tùy chọn jsonp thành false ngăn cản jQuery thêm chuỗi ?callback vào URL hoặc cố gắng sử dụng =? để chuyển đổi. Trong trường hợp này, bạn cũng nên đặt rõ ràng cài đặt jsonpCallback.Ví dụ, { jsonp: false, jsonpCallback: "callbackName" }

http://api.jquery.com/jQuery.ajax/

jQuery thêm ?callback=jQuery17109492628197185695_1339420031913 và sau đó thiết lập các dữ liệu yêu cầu như tham số để gọi lại này, vì vậy bạn sẽ có:

jQuery17109492628197185695_1339420031913({ 
    "status": 200, 
    "data": {your json} 
}) 

Để tránh thiết lập thông số bổ sung để yêu cầu một địa chỉ URL và gọi gọi lại, thêm tham số này để phương pháp ajax: jsonp:false, vì vậy nó sẽ trông giống như:

$.ajax({ 
    ... 
    jsonp:false, 
    ... 
}); 
0

Câu trả lời của Trevor Burnham khá tốt, nhưng thay vì theo dõi số lượng yêu cầu, bạn chỉ nên so sánh yêu cầu với tham số XHR, như vậy;

doRequest: function() { 
    this._freeRequest(); 

    this._request = $.getJSON(url + params + '&callback=?', function(response, status, xhr) { 
     if (this._request !== xhr) return; // aborted 

     // success 
    }.bind(this)).done(this._freeRequest.bind(this)); 
} 

_freeRequest: function() { 
    if (this._request) { 
     delete this._request; 
    } 
} 

Calling doRequest lại hoặc _freeRequest một lần trước khi yêu cầu trước đó đã hoàn thành, sẽ dẫn đến việc "phá thai" của nói yêu cầu bằng cách làm cho dòng if (this._request !== xhr) để trở thành hiện thực, vì this._request sẽ hoặc bị xóa hoặc yêu cầu khác hoàn toàn.

1

Đừng hủy bỏ yêu cầu

Chỉ cần lưu trữ một nơi nào đó XHR đối tượng

theXHR = $.ajax(.... 

Nếu người dùng hủy bỏ yêu cầu vô đối tượng lưu

// user canceled 
theXHR = null; 

Cuối cùng khi bạn nhận được phản hồi (success gọi lại) cuộc gọi lại wi sẽ so sánh đối tượng XHR của phản hồi với đối tượng đã lưu.

function successCallback(data, textStatus, XHR) 
{ 
    if(theXHR !== XHR) 
    { 
     // user canceled; discard the response 
     return; 
    } 

    // process the response 
} 

Không có lỗi jQuery.


Là lời khuyên chung không dựa trên abort(), ngay cả đối với yêu cầu ajax thông thường.

  1. Trong bất kỳ trường hợp bạn sẽ không tiết kiệm tài nguyên trên máy chủ bacause yêu cầu bạn gửi sẽ được xử lý và không có cách nào để ngăn chặn nó. Và một phản ứng sẽ trở lại.

  2. Một số trình duyệt cũ hơn xử lý abort() không đúng cách.

Chỉ cần "bộ nhớ cache" đối tượng XHR và xử lý các CANCEL kịch bản cho mình.

Các vấn đề liên quan