Làm cách nào để bắt lỗi jQuery $ .getJSON (hoặc $ .ajax với kiểu dữ liệu được đặt thành 'jsonp') khi sử dụng JSONP?


76

Có thể gặp lỗi khi sử dụng JSONP với jQuery không? Tôi đã thử cả hai phương pháp $ .getJSON và $ .ajax nhưng đều không bắt được lỗi 404 mà tôi đang thử nghiệm. Đây là những gì tôi đã thử (hãy nhớ rằng tất cả những thứ này đều hoạt động thành công, nhưng tôi muốn xử lý trường hợp nó không thành công):

jQuery.ajax({
    type: "GET",
    url: handlerURL,
    dataType: "jsonp",
    success: function(results){
        alert("Success!");
    },
    error: function(XMLHttpRequest, textStatus, errorThrown){
        alert("Error");
    }
});

Và ngoài ra:

jQuery.getJSON(handlerURL + "&callback=?", 
    function(jsonResult){
        alert("Success!");
    });

Tôi cũng đã thử thêm $ .ajaxError nhưng điều đó cũng không hoạt động:

jQuery(document).ajaxError(function(event, request, settings){
   alert("Error");
});

Cảm ơn trước cho bất kỳ trả lời!


Có gì sai khi sử dụng 'error: function () {}' ??
James

1
Nó không bắn. (Hãy nhớ đây là JSONP).
Andy ngày

Câu trả lời:


51

Có vẻ như các yêu cầu JSONP không trả về kết quả thành công sẽ không bao giờ kích hoạt bất kỳ sự kiện nào, thành công hay thất bại và tốt hơn hay tệ hơn đó là do thiết kế.

Sau khi tìm kiếm trình theo dõi lỗi của họ, có một bản vá có thể là giải pháp khả thi bằng cách sử dụng gọi lại thời gian chờ. Xem báo cáo lỗi # 3442 . Nếu bạn không thể nắm bắt được lỗi, ít nhất bạn có thể hết thời gian chờ sau một khoảng thời gian hợp lý để thành công.


Liên kết báo cáo lỗi # 3442 bị hỏng. Đây có lẽ là liên kết chính xác: Ticket # 3442 (đóng cửa cải tiến: đã sửa)
hippietrail.

Đã đồng ý !!! một câu hỏi, Mặc dù tôi đang thực hiện cuộc gọi JSONP và gặp lỗi 404 nhưng tôi không nhận được 406 và 401 ??? tại sao ??? stackoverflow.com/questions/18570486/…
Hitesh

câu trả lời sai, một trong những quyền là một trong đó mô tả sử dụng .fail (function ())
jumpjack

Câu trả lời này sẽ không còn đúng nữa (nữa?) Stackoverflow.com/a/19075701/2617354 là cách chính xác để thực hiện.
Daywalker

53

Đây là câu trả lời mở rộng của tôi cho một câu hỏi tương tự.

Đây là mã:

jQuery.getJSON(handlerURL + "&callback=?", 
    function(jsonResult){
        alert("Success!");
    })
.done(function() { alert('getJSON request succeeded!'); })
.fail(function(jqXHR, textStatus, errorThrown) { alert('getJSON request failed! ' + textStatus); })
.always(function() { alert('getJSON request ended!'); });

12
Tôi không hiểu tại sao điều này không có nhiều ủng hộ hơn. Đây rõ ràng là cách xử lý lỗi được cho là sẽ xảy ra. Tại sao câu trả lời được chấp nhận lại nói rằng "Có vẻ như các yêu cầu JSONP không trả về kết quả thành công không bao giờ kích hoạt bất kỳ sự kiện nào, thành công hay thất bại" khi điều này rõ ràng là không đúng sự thật ??? Những điều tôi không hiểu.
phil294

Sau khi đọc kỹ hơn một chút, tôi nghĩ rằng nó phải làm, đó là năm 2008 mọi thứ có một chút khác biệt trong jQuery;)
Daywalker

@Daywalker vâng, các phương thức thành công / lỗi / hoàn thành không được dùng nữa và bị xóa kể từ JQuery 3.0 ( api.jquery.com/jQuery.get )
user2314737

16

Phát hiện sự cố JSONP

Nếu bạn không muốn tải xuống phần phụ thuộc, bạn có thể tự phát hiện trạng thái lỗi. Dễ thôi.

Bạn sẽ chỉ có thể phát hiện lỗi JSONP bằng cách sử dụng một số loại thời gian chờ. Nếu không có phản hồi hợp lệ trong một thời gian nhất định, thì giả sử có lỗi. Tuy nhiên, lỗi về cơ bản có thể là bất cứ điều gì.

Đây là một cách đơn giản để kiểm tra lỗi. Chỉ cần sử dụng một successlá cờ:

var success = false;

$.getJSON(url, function(json) {
    success = true;
    // ... whatever else your callback needs to do ...
});

// Set a 5-second (or however long you want) timeout to check for errors
setTimeout(function() {
    if (!success)
    {
        // Handle error accordingly
        alert("Houston, we have a problem.");
    }
}, 5000);

Như thedawnrider đã đề cập trong nhận xét, bạn cũng có thể sử dụng clearTimeout để thay thế:

var errorTimeout = setTimeout(function() {
    if (!success)
    {
        // Handle error accordingly
        alert("Houston, we have a problem.");
    }
}, 5000);

$.getJSON(url, function(json) {
    clearTimeout(errorTimeout);
    // ... whatever else your callback needs to do ...
});

Tại sao? Đọc tiếp ...


Tóm lại, đây là cách JSONP hoạt động:

JSONP không sử dụng XMLHttpRequest như các yêu cầu AJAX thông thường. Thay vào đó, nó đưa một <script>thẻ vào trang, trong đó thuộc tính "src" là URL của yêu cầu. Nội dung của phản hồi được bao bọc trong một hàm Javascript, sau đó sẽ được thực thi khi tải xuống.

Ví dụ.

Yêu cầu JSONP: https://api.site.com/endpoint?this=that&callback=myFunc

Javascript sẽ đưa thẻ script này vào DOM:

<script src="https://api.site.com/endpoint?this=that&callback=myFunc"></script>

Điều gì xảy ra khi <script> thẻ được thêm vào DOM? Rõ ràng, nó được thực thi.

Vì vậy, giả sử phản hồi cho truy vấn này mang lại kết quả JSON như:

{"answer":42}

Đối với trình duyệt, đó là thứ giống như nguồn của tập lệnh, vì vậy nó được thực thi. Nhưng điều gì sẽ xảy ra khi bạn thực hiện điều này:

<script>{"answer":42}</script>

Cũng không có gì. Nó chỉ là một đối tượng. Nó không được lưu trữ, lưu trữ và không có gì xảy ra.

Đây là lý do tại sao các yêu cầu JSONP gói kết quả của chúng trong một hàm. Máy chủ, phải hỗ trợ tuần tự hóa JSONP, nhìn thấy callbacktham số bạn đã chỉ định và trả về thông số này thay thế:

myFunc({"answer":42})

Sau đó, điều này được thực thi thay thế:

<script>myFunc({"answer":42})</script>

... hữu ích hơn nhiều. Ở đâu đó trong mã của bạn, trong trường hợp này, một hàm toàn cục được gọi là myFunc:

myFunc(data)
{
    alert("The answer to life, the universe, and everything is: " + data.answer);
}

Đó là nó. Đó là "điều kỳ diệu" của JSONP. Sau đó, để xây dựng trong một kiểm tra thời gian chờ rất đơn giản, như được hiển thị ở trên. Thực hiện yêu cầu và ngay sau đó, bắt đầu thời gian chờ. Sau X giây, nếu cờ của bạn vẫn chưa được đặt thì yêu cầu đã hết thời gian chờ.


1
Bạn cũng có thể sử dụng jsonpFailCheck = setTimeout(...)và sau đó thay vì success=truebạn sẽ sử dụngclearTimeout(jsonpFailCheck)
iancoleman

14

Tôi biết câu hỏi này hơi cũ nhưng tôi không thấy câu trả lời đưa ra giải pháp đơn giản cho vấn đề nên tôi nghĩ tôi sẽ chia sẻ giải pháp 'đơn giản' của mình.

$.getJSON("example.json", function() {
      console.log( "success" );
}).fail(function() { 
      console.log( "error" ); 
}); 

Chúng tôi chỉ cần sử dụng lệnh .fail()gọi lại để kiểm tra xem có xảy ra lỗi hay không.

Hi vọng điêu nay co ich :)


2
Lưu ý rằng điều này chỉ có tác dụng trong phiên bản 2.x (mà đã giảm hỗ trợ cho IE <= 8), không phải trong 1.x
Laurens Rietveld

@LaurensRietveld Nó đã được hỗ trợ kể từ v1: api.jquery.com/jQuery.getJSON
Farhan Ahmad

3

Nếu bạn cộng tác với nhà cung cấp, bạn có thể gửi một tham số chuỗi truy vấn khác là hàm để gọi lại khi có lỗi.

? callback =? & error =?

Đây được gọi là JSONPE nhưng hoàn toàn không phải là tiêu chuẩn defacto.

Sau đó, nhà cung cấp chuyển thông tin đến chức năng lỗi để giúp bạn chẩn đoán.

Tuy nhiên, không giúp được lỗi comm - jQuery sẽ phải được cập nhật để gọi lại hàm lỗi khi hết thời gian chờ, như trong câu trả lời của Adam Bellaire.


2

Có vẻ như điều này đang hoạt động ngay bây giờ:

jQuery(document).ajaxError(function(event, request, settings){
   alert("Error");
});

Chỉ cho jquery 2.x, không 1.x
Laurens Rietveld

1

Tôi sử dụng cái này để bắt lỗi JSON

try {
   $.getJSON(ajaxURL,callback).ajaxError();
} catch(err) {
   alert("wow");
   alert("Error : "+ err);
}

Chỉnh sửa: Ngoài ra, bạn cũng có thể nhận được thông báo lỗi. Điều này sẽ cho bạn biết chính xác lỗi là gì. Hãy thử cú pháp sau trong khối bắt

alert("Error : " + err);

3
Làm cách nào bạn có thể thực hiện thử / bắt cuộc gọi không đồng bộ? Cuộc gọi kết thúc ngay lập tức khi có liên quan đến việc thử / bắt. Việc gọi lại, hoặc bất kỳ lỗi nào, xảy ra sau đó rất lâu sau khi chúng tôi đã rời khỏi phạm vi của mã này .
Gone Coding

0

Mayby này hoạt động?

.complete(function(response, status) {
    if (response.status == "404")
        alert("404 Error");
    else{
        //Do something
    }   
    if(status == "error")
        alert("Error");
    else{
        //Do something
    }
});

Tôi không biết bất cứ khi nào trạng thái chuyển sang chế độ "lỗi". Nhưng tôi đã thử nghiệm nó với 404 và nó phản hồi


thậm chí chúng tôi có thể kiểm tra trạng thái phản hồi cho chức năng lỗi. Tốt hơn chúng ta có thể sử dụng chức năng lỗi.
iamjustcoder

0

bạn có thể xử lý rõ ràng bất kỳ số lỗi nào bằng cách thêm thuộc tính này trong yêu cầu ajax:

statusCode: {
        404: function() {
          alert("page not found");
        }
    }

vì vậy, mã của bạn sẽ như thế này:

jQuery.ajax({
type: "GET",
statusCode: {
        404: function() {
          alert("page not found");
        }
},
url: handlerURL,
dataType: "jsonp",
success: function(results){
    alert("Success!");
},
error: function(XMLHttpRequest, textStatus, errorThrown){
    alert("Error");
}
});

hy vọng điều này sẽ giúp bạn :)


0

Tôi cũng đã đăng câu trả lời này trong phần tràn ngăn xếp - Xử lý lỗi trong cuộc gọi getJSON

Tôi biết đã lâu rồi kể từ khi ai đó trả lời ở đây và người đăng có thể đã nhận được câu trả lời của mình từ đây hoặc từ một nơi khác. Tuy nhiên, tôi nghĩ rằng bài đăng này sẽ giúp ích cho bất kỳ ai đang tìm cách theo dõi lỗi và thời gian chờ khi thực hiện các yêu cầu getJSON. Do đó, dưới đây câu trả lời của tôi cho câu hỏi

Cấu trúc getJSON như sau (tìm thấy trên http://api.jqueri.com ):

$(selector).getJSON(url,data,success(data,status,xhr))

hầu hết mọi người thực hiện điều đó bằng cách sử dụng

$.getJSON(url, datatosend, function(data){
    //do something with the data
});

nơi họ sử dụng url var để cung cấp liên kết đến dữ liệu JSON, dữ liệu và dữ liệu làm nơi để thêm "?callback=?" và các biến khác phải được gửi để nhận được dữ liệu JSON chính xác được trả về và chức năng thành công như một hàm để xử lý dữ liệu .

Tuy nhiên, bạn có thể thêm các biến trạng thái và xhr trong hàm thành công của mình. Biến trạng thái chứa một trong các chuỗi sau: "thành công", "không được sửa đổi", "lỗi", "thời gian chờ" hoặc "lỗi phân tích cú pháp" và biến xhr chứa đối tượng XMLHttpRequest trả về ( tìm thấy trên w3schools )

$.getJSON(url, datatosend, function(data, status, xhr){
    if (status == "success"){
        //do something with the data
    }else if (status == "timeout"){
        alert("Something is wrong with the connection");
    }else if (status == "error" || status == "parsererror" ){
        alert("An error occured");
    }else{
        alert("datatosend did not change");
    }         
});

Bằng cách này, có thể dễ dàng theo dõi thời gian chờ và lỗi mà không cần phải triển khai trình theo dõi thời gian chờ tùy chỉnh được khởi động sau khi yêu cầu được thực hiện.

Hy vọng điều này sẽ giúp ai đó vẫn đang tìm kiếm câu trả lời cho câu hỏi này.


Xin lỗi nhưng điều này không tạo ra gì với jQuery 2.2.3.
PhilPhil
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.