เกิดข้อผิดพลาดในการจัดการกับการโทรด้วย GetJSON


192

คุณจะจัดการกับข้อผิดพลาดในการโทรของ GetJSON ได้อย่างไร ฉันพยายามอ้างอิงบริการสคริปต์ข้ามโดเมนโดยใช้ jsonp คุณจะลงทะเบียนวิธีข้อผิดพลาดได้อย่างไร



ใช่ทำไมไม่ลองพิจารณาการทำเครื่องหมายคำตอบที่ถูกต้อง
IonicăBizău

@ IonicăBizăuทำเครื่องหมายทันที ฉันเพิ่งหลงทางไปซักพักแล้ว คำตอบอันดับต้นไม่ได้พูดถึง JSONP ในฐานะที่เป็นออกแหลมเบน Shelock ไม่มีจัดการข้อผิดพลาดการสนับสนุนคือสิ่งที่ผมเชื่อว่า ..
Ajay

คำตอบ:


277

$.getJSON() เป็นนามธรรมของการโทร AJAX ปกติที่คุณจะต้องบอกว่าคุณต้องการการตอบสนองที่เข้ารหัส JSON

$.ajax({
  url: url,
  dataType: 'json',
  data: data,
  success: callback
});

คุณสามารถจัดการข้อผิดพลาดได้สองวิธี: โดยทั่วไป (โดยการกำหนดค่าการโทร AJAX ของคุณก่อนที่จะเรียกพวกเขาจริง ๆ ) หรือโดยเฉพาะ (ด้วยห่วงโซ่วิธีการ)

'generic' จะเป็นสิ่งที่ต้องการ:

$.ajaxSetup({
      "error":function() { alert("error");  }
});

และวิธีการ 'เฉพาะ':

$.getJSON("example.json", function() {
  alert("success");
})
.success(function() { alert("second success"); })
.error(function() { alert("error"); })
.complete(function() { alert("complete"); });

nops! คุณสามารถไปได้ตามที่คุณต้องการ ดูเอกสารเพื่อขอความช่วยเหลืออย่างละเอียดเพิ่มเติม: http://api.jquery.com/jQuery.ajax
Luciano Costa

5
โปรดทราบว่านี่ต้องใช้ jQuery 1.5+ (พยายามทำให้มันใช้งานได้ด้วย jQuery 1.3 และสงสัยว่าทำไมมันถึงบ่นเกี่ยวกับวิธีการที่ไม่ถูกต้อง :-)
kenyee

24
OP กำลังถามเฉพาะเกี่ยวกับ cross-site ซึ่งJSONPดูเหมือนว่าgetJSONในกรณีดังกล่าวไม่ได้เรียกใช้error()ฟังก์ชัน ฉันมีปัญหาเดียวกัน ฉันเดาว่ามันเกี่ยวข้องกับวิธีการJSONPจัดการที่แตกต่างอย่างสิ้นเชิงกับการAJAXโทรปกติjQueryทั้งๆที่getJSONจัดการทั้งสองอย่าง JSONจะกระทำกับXMLHTTPRequestวัตถุ แต่JSONPจะกระทำโดยแบบไดนามิกการเพิ่มแท็กไปยังหน้า<script> HEAD
hippietrail

3
jQuery Doc กล่าวว่า "หมายเหตุ: ตัวจัดการนี้ไม่ได้ถูกเรียกใช้สำหรับสคริปต์ข้ามโดเมนและคำขอ JSONP" api.jquery.com/jQuery.ajax > ข้อผิดพลาด
OneWorld

10
"วิธีการโทรกลับ jqXHR.success (), jqXHR.error () และ jqXHR.complete () ที่แนะนำใน jQuery 1.5 นั้นเลิกใช้แล้วเป็น jQuery 1.8 เมื่อต้องการเตรียมรหัสของคุณสำหรับการลบในที่สุดให้ใช้ jqXHR.done (), jqXHR .fail () และ jqXHR.always () แทน "
Skorunka František

86

มีคนให้คะแนนเหล่านี้กับ Luciano :) ฉันเพิ่งทดสอบคำตอบของเขา - มีคำถามที่คล้ายกัน - และทำงานอย่างสมบูรณ์ ...

ฉันยังเพิ่ม 50 เซ็นต์ของฉัน:

.error(function(jqXHR, textStatus, errorThrown) {
        console.log("error " + textStatus);
        console.log("incoming Text " + jqXHR.responseText);
    })

3
สิ่งนี้มากับ JSONP ข้ามไซต์หรือกับ JSON ของไซต์เดียวกันหรือไม่
hippietrail

28
คำตอบที่ดี! เพียงแค่ทราบเกี่ยวกับ .error: มันจะไม่สนับสนุนใน jQuery 1.8 ดังนั้นให้ใช้. mail
Anatoly Mironov

73

นี่คือการเพิ่มของฉัน

จากhttp://www.learnjavascript.co.uk/jq/reference/ajax/getjson.htmlและแหล่งที่มาอย่างเป็นทางการ

" วิธีการโทรกลับ jqXHR.success (), jqXHR.error () และ jqXHR.complete () ที่แนะนำใน jQuery 1.5 นั้นเลิกใช้แล้วเป็น jQuery 1.8 เพื่อเตรียมโค้ดของคุณสำหรับการลบในที่สุดให้ใช้ jqXHR.done (), jqXHR .fail () และ jqXHR.always () แทน "

ฉันทำอย่างนั้นและนี่คือตัวอย่างรหัสปรับปรุงของ Luciano:

$.getJSON("example.json", function() {
  alert("success");
})
.done(function() { alert('getJSON request succeeded!'); })
.fail(function() { alert('getJSON request failed! '); })
.always(function() { alert('getJSON request ended!'); });

และมีคำอธิบายข้อผิดพลาดพร้อมแสดงข้อมูล json ทั้งหมดเป็นสตริง:

$.getJSON("example.json", function(data) {
  alert(JSON.stringify(data));
})
.done(function() { alert('getJSON request succeeded!'); })
.fail(function(jqXHR, textStatus, errorThrown) { alert('getJSON request failed! ' + textStatus); })
.always(function() { alert('getJSON request ended!'); });

หากคุณไม่ชอบการแจ้งเตือนให้แทนที่ด้วย console.log

$.getJSON("example.json", function(data) {
  console.log(JSON.stringify(data));
})
.done(function() { console.log('getJSON request succeeded!'); })
.fail(function(jqXHR, textStatus, errorThrown) { console.log('getJSON request failed! ' + textStatus); })
.always(function() { console.log('getJSON request ended!'); });

ลำดับของการทำอะไรล้มเหลวเสมอและรหัสภายใน getJSON
TheLogicGuy

หมายเหตุ: console.log ไม่ได้ใช้งานในเบราว์เซอร์รุ่นเก่าเช่น IE7! ในกรณีที่คุณใช้มัน!
MadMad666

12

ฉันรู้ว่าเป็นเวลานานแล้วที่มีคนตอบคำถามที่นี่และโปสเตอร์อาจได้คำตอบจากที่นี่หรือจากที่อื่น อย่างไรก็ตามฉันคิดว่าโพสต์นี้จะช่วยให้ทุกคนที่กำลังมองหาวิธีในการติดตามข้อผิดพลาดและหมดเวลาในขณะที่ทำคำขอของ GetJSON ดังนั้นใต้คำตอบของคำถาม

โครงสร้าง getJSON มีดังนี้ (พบได้ที่http://api.jqueri.com ):

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

คนส่วนใหญ่ใช้งานที่ใช้

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

โดยที่พวกเขาใช้ url var เพื่อจัดทำลิงก์ไปยังข้อมูล JSON, DataTendend เป็นสถานที่ในการเพิ่ม"?callback=?"และตัวแปรอื่น ๆ ที่ต้องส่งเพื่อรับข้อมูล JSON ที่ถูกต้องที่ส่งคืนและฟังก์ชั่นความสำเร็จเป็นฟังก์ชันสำหรับการประมวลผลข้อมูล .

อย่างไรก็ตามคุณสามารถเพิ่มสถานะและตัวแปร xhr ในฟังก์ชันความสำเร็จของคุณ ตัวแปรสถานะมีหนึ่งในสตริงต่อไปนี้: "สำเร็จ", "ไม่ได้แก้ไข", "ข้อผิดพลาด", "หมดเวลา" หรือ "parsererror" และตัวแปร xhr มีวัตถุ XMLHttpRequest ที่ส่งคืน ( พบใน 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");
    }         
});

วิธีนี้ทำให้ง่ายต่อการติดตามการหมดเวลาและข้อผิดพลาดโดยไม่ต้องใช้ตัวติดตามการหมดเวลาที่กำหนดเองที่เริ่มต้นเมื่อมีการร้องขอ

หวังว่านี่จะช่วยให้บางคนยังคงมองหาคำตอบสำหรับคำถามนี้


2
มันใช้งานไม่ได้ การเรียกกลับ "สำเร็จ" ตามชื่อมีความหมายว่าเรียกสำเร็จเท่านั้น (ดังนั้นฉันไม่แน่ใจว่าพารามิเตอร์ "status" สำหรับ ... )
อะไร jwelsh

4

$.getJSON("example.json", function() {
  alert("success");
})
.success(function() { alert("second success"); })
.error(function() { alert("error"); })

มันได้รับการแก้ไขใน jQuery 2.x; ใน jQuery 1.x คุณจะไม่ได้รับข้อผิดพลาดในการโทรกลับ


1

ฉันประสบกับปัญหาเดียวกันนี้ แต่แทนที่จะสร้างการเรียกกลับสำหรับคำขอที่ล้มเหลวฉันเพียงแค่ส่งคืนข้อผิดพลาดกับวัตถุข้อมูล json

ถ้าเป็นไปได้ดูเหมือนว่าจะเป็นทางออกที่ง่ายที่สุด นี่คือตัวอย่างของรหัส Python ที่ฉันใช้ (ใช้ Flask, jsonify ของ Flask และ SQLAlchemy)

try:
    snip = Snip.query.filter_by(user_id=current_user.get_id(), id=snip_id).first()
    db.session.delete(snip)
    db.session.commit()
    return jsonify(success=True)
except Exception, e:
    logging.debug(e)
    return jsonify(error="Sorry, we couldn't delete that clip.")

จากนั้นคุณสามารถตรวจสอบ Javascript เช่นนี้

$.getJSON('/ajax/deleteSnip/' + data_id,
    function(data){
    console.log(data);
    if (data.success === true) {
       console.log("successfully deleted snip");
       $('.snippet[data-id="' + data_id + '"]').slideUp();
    }
    else {
       //only shows if the data object was returned
    }
});

นี่เป็นเรื่องปกติสำหรับข้อผิดพลาดที่เกิดขึ้นภายในเซิร์ฟเวอร์ แต่จะไม่ดักจับเมื่อการโทรไม่สามารถไปถึงเซิร์ฟเวอร์หรือหากมีข้อผิดพลาดเกิดขึ้นก่อนที่จะถึงรหัสเซิร์ฟเวอร์เช่นหากผู้ใช้ MVC ไม่ได้รับการรับรองความถูกต้องอีกต่อไป
Lee Oades

1

ทำไมจะไม่ล่ะ

getJSON('get.php',{cmd:"1", typeID:$('#typesSelect')},function(data) {
    // ...
});

function getJSON(url,params,callback) {
    return $.getJSON(url,params,callback)
        .fail(function(jqXMLHttpRequest,textStatus,errorThrown) {
            console.dir(jqXMLHttpRequest);
            alert('Ajax data request failed: "'+textStatus+':'+errorThrown+'" - see javascript console for details.');
        })
}

??

สำหรับรายละเอียดเกี่ยวกับ.fail()วิธีการที่ใช้(jQuery 1.5+) โปรดดู http://api.jquery.com/jQuery.ajax/#jqXHR

เนื่องจากjqXHRฟังก์ชั่นถูกส่งกลับโดยการผูกมัดเช่น

$.when(getJSON(...)).then(function() { ... });

เป็นไปได้.


0

ในบางกรณีคุณอาจพบปัญหาการซิงโครไนซ์ด้วยวิธีนี้ ฉันเขียนโทรกลับภายในsetTimeoutฟังก์ชั่นและมันทำงานพร้อมกันได้ดี =)

เช่น:

function obterJson(callback) {


    jqxhr = $.getJSON(window.location.href + "js/data.json", function(data) {

    setTimeout(function(){
        callback(data);
    },0);
}

0

นี่เป็นเธรดเก่า แต่มีขึ้นในการค้นหาของ Google ดังนั้นฉันคิดว่าฉันจะเพิ่ม jQuery 3 คำตอบโดยใช้สัญญา ตัวอย่างนี้แสดง:

  • คุณไม่จำเป็นต้องเปลี่ยนเป็น $ .ajax เพื่อส่งต่อโทเค็นผู้ถือของคุณอีกต่อไป
  • ใช้. แล้ว () เพื่อให้แน่ใจว่าคุณสามารถประมวลผลผลลัพธ์ใด ๆ (ฉันเจอปัญหานี้. เสมอ () โทรกลับยิงเร็วเกินไป - แม้ว่าฉันไม่แน่ใจว่าเป็นของจริง 100%)
  • ฉันใช้. always () เพื่อแสดงผลลัพธ์ไม่ว่าจะเป็นบวกหรือลบ
  • ในฟังก์ชัน. always () ฉันกำลังอัปเดตเป้าหมายสองรายการด้วยรหัสสถานะ HTTP และเนื้อหาข้อความ

ข้อมูลโค้ดคือ:

    $.getJSON({
         url: "https://myurl.com/api",
         headers: { "Authorization": "Bearer " + user.access_token}
    }).then().always(   function (data, textStatus) {
        $("#txtAPIStatus").html(data.status);
        $("#txtAPIValue").html(data.responseText);
    });
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.