2009-05-11 20 views
10

Ich benutze ASP.Net MVC, aber das gilt für jedes Framework.jQuery AJAX und Umgang mit verschiedenen dataTypes

Ich mache einen Ajax-Aufruf an meinen Server, der die meiste Zeit einfach alten HTML zurückgibt, aber wenn es einen Fehler gibt, möchte ich ein JSON-Objekt mit einer Statusmeldung (und ein paar andere Dinge). Es scheint keinen Weg für die dataType Option in der jQuery-Aufruf zu sein, damit gut umzugehen. Standardmäßig scheint alles als html zu parsen, was dazu führt, dass <div> mit "{ status: 'error', message: 'something bad happened'}" gefüllt wird.

[Bearbeiten] Das dataType Objekt zu ignorieren und jQuery herauszufinden, funktioniert auch nicht. Es sieht den Typ des Ergebnisses als string und behandelt es als HTML.

Eine Lösung, die ich gefunden habe, ist, das Ergebnisobjekt als JSON zu parsen. Wenn das funktioniert, wissen wir, dass es ein JSON-Objekt ist. Wenn es eine Ausnahme auslöst, es HTML ist:

$.ajax({ 
    data: {}, 
    success: function(data, textStatus) { 
     try { 
      var errorObj = JSON.parse(data); 
      handleError(errorObj); 
     } catch(ex) { 
      $('#results').html(data); 
     } 
    }, 
    dataType: 'html', // sometimes it is 'json' :-/ 
    url: '/home/AjaxTest', 
    type: 'POST' 
}); 

jedoch eine Ausnahme in dieser Art und Weise unter Verwendung kommt mir ziemlich schlechtes Design (und nicht intuitiv, gelinde gesagt). Gibt es einen besseren Weg? Ich dachte daran, die gesamte Antwort in ein JSON-Objekt zu verpacken, aber in diesem Fall halte ich das nicht für eine Option.

Hier ist die Lösung, die ich von Steve Willcock bekam:

// ASP.NET MVC Action: 
[AcceptVerbs(HttpVerbs.Post)] 
public ActionResult AjaxTest(int magic) { 
    try { 
     var someVal = GetValue(); 
     return PartialView("DataPage", someVal); 
    } catch (Exception ex) { 
     this.HttpContext.Response.StatusCode = 500; 
     return Json(new { status = "Error", message = ex.Message }); 
    } 
} 




// jQuery call: 

$.ajax({ 
    data: {}, 
    success: function(data, textStatus) { 
     $('#results').html(data); 
    }, 
    error: function() { 
     var errorObj = JSON.parse(XMLHttpRequest.responseText); 
     handleError(errorObj); 
    }, 
    dataType: 'html', 
    url: '/home/AjaxTest', 
    type: 'POST' 
}); 
+0

Hmmm, interessante Situation, aber ich weiß nicht, ob ein Verfahren mit unterschiedlichen Typen zurückgeben ist die beste Idee - vielleicht sollten Sie die erste Methode ein bool zurückgeben, und dann in dem .ajax Rückruf $ können Sie Rufen Sie eine andere Methode auf, die die Statusmeldung zurückgibt. –

Antwort

9

Für Ihre JSON-Fehler konnten Sie einen 500-Statuscode vom Server anstelle von 200 zurückgeben. Dann kann der jquery-Clientcode den error: -Handler für die $ .ajax-Funktion zur Fehlerbehandlung verwenden. Bei einer 500-Antwort können Sie das JSON-Fehlerobjekt aus dem ResponseText analysieren, bei einer 200-Antwort können Sie Ihren HTML-Code einfach in einem div wie gewohnt verschachteln.

+0

Huh. Großartige Idee. –

+0

Fantastisch. Ich bin ein bisschen weiser, 500 für etwas anderes als einen kritischen Fehler zu verwenden, aber ich denke, es ist immer noch die beste Option hier. Ich werde den Beitrag bearbeiten, um Code anzuzeigen. – swilliams

+3

400 (schlechte Anfrage) kann besser sein als 500 ... –

6

Während Steves Idee gut ist, ich bin dies auf Vollständigkeit in hinzufügen.

Es scheint, dass wenn Sie einen dataType von JSON angeben, aber HTML zurückgeben, jQuery es gut behandelt.

testete ich diese Theorie mit dem folgenden Code:

if($_GET['type'] == 'json') { 
    header('Content-type: application/json'); 
    print '{"test":"hi"}'; 
    exit; 
} else { 
    header('Content-type: text/html'); 
    print '<html><body><b>Test</b></body></html>'; 
    exit; 
} 

Die $_GET['type'] ist nur so kann ich kontrollieren, was während des Tests zurückzukehren. In Ihrer Situation würden Sie das eine oder andere zurückgeben, je nachdem, ob die Dinge richtig oder falsch gelaufen sind. Vergangenheit, dass mit diesem jQuery-Code:

$.ajax({ 
    url: 'php.php?type=html', // return HTML in this test 
    dataType: 'json', 
    success: function(d) { 
     console.log(typeof d); // 'xml' 
    } 
}); 

Auch wenn wir JSON als Datentyp angegeben, jQuery (1.3.2) finden heraus, dass sie das nicht.

$.ajax({ 
    url: 'php.php?type=json', 
    dataType: 'json', 
    success: function(d) { 
     console.log(typeof d); // 'object' 
    } 
}); 

So können Sie nutzen (soweit ich weiß) undokumentiertes Verhalten zu tun, was Sie wollen.

+0

Dies kann eine Funktion von ASP.Net MVC sein, aber der Typ der Daten gibt 'string' sowohl für HTML- als auch für JSON-Ergebnisse an, daher erhält es Handles als HTML. – swilliams

+0

Mm. Eine Sekunde. –

+0

Die Antwort, die ASP.NET von ASP.NET MVC erhält, wird als Fehler analysiert. Wenn ich den error() - Callback von jQuery handhabe, kann ich den HTML-Code bekommen ... der funktioniert, aber wie mein Ausnahmecode, scheint nicht "richtig" zu sein. Wenn ich PHP verwenden würde, wäre dies definitiv eine gültige Lösung. – swilliams

3

Aber warum nicht nur JSON ungeachtet des Status (Erfolg oder Fehler) auf dem POST und die Verwendung eines GET, um die Ergebnisse anzuzeigen?
Es scheint wie ein besserer Ansatz, wenn Sie mich fragen.

0

Oder Sie könnten immer eine JSON-Antwort zurückgeben und einen Parameter als HTML-Inhalt haben.

Etwas wie:

{ 
    "success" : true, 
    "errormessage" : "", 
    "html" : "<div>blah</div>", 
} 

Ich glaube, Sie würden nur doppelte Anführungszeichen in dem HTML-Wert und der json Parser würde für Sie, dass entkommen rückgängig zu machen.

+0

Das ist leider extrem schnell kompliziert. – swilliams

0

Ich lief genau in diesem Problem mit MVC/Ajax/JQuery und wollte mehrere dataTypes (JSON und HTML) verwenden. Ich habe eine AJAX-Anfrage, um einen HTML-Datentyp zu verwenden, um die Daten zurückzugeben, aber ich versuche, die Daten, die von der Ajax-Anfrage zurückkommen, in ein JSON-Objekt zu konvertieren. Ich habe eine Funktion wie diese, die ich von meinem Erfolg Rückruf nennen:

_tryParseJson: function (data) { 
     var jsonObject; 

     try { 
      jsonObject = jQuery.parseJSON(data); 
     } 
     catch (err) { 
     } 

     return jsonObject; 
    } 

ich dann davon ausgehen, dass, wenn die JSONObject und Errormessage-Eigenschaft geben, dass ein Fehler aufgetreten ist, sonst wird ein Fehler nicht aufgetreten wäre.

0

Ich erreichte dies mit den Ajax-Erfolg und Fehlerrückrufe nur. Auf diese Weise kann ich die Antworten der Strings und JSON-Objekte vom Server gemischt haben.

Unten bin ich bereit, json zu akzeptieren, aber wenn ich einen Status von "parsererror" bekomme (was bedeutet, dass jquery den eingehenden Code nicht als json analysieren konnte, da dies das ist, was ich erwartete), aber es hat einen Anforderungsstatus von "OK" (200), dann behandle ich die Antwort als String. Alles andere als ein "parsererror" und "OK" behandle ich als Fehler.

$.ajax({ 
    dataType: 'json', 
    url: '/ajax/test', 
    success: function (resp) { 
     // your response json object, see if status was set to error 
     if (resp.status == 'error') { 
     // log the detail error for the dev, and show the user a fail 
     console.log(resp); 
     $('#results').html('error occurred'); 
     } 
     // you could handle other cases here 
     // or use a switch statement on the status value 
    }, 
    error: function(request, status, error) { 
     // if json parse error and a 200 response, we expect this is our string 
     if(status == "parsererror" && request.statusText == "OK") { 
     $('#results').html(request.responseText); 
     } else { 
     // again an error, but now more detailed and not a parser error 
     // and we'll log for dev and show the user a fail 
     console.log(status + ": " + error.message); 
     $('#results').html('error occurred'); 
     } 
    } 
    }); 
Verwandte Themen