[javascript] jQuery gibt "parsererror" für die Ajax-Anforderung zurück



Answers

In der answer von @ david-east finden Sie den richtigen Umgang mit dem Problem

Diese Antwort ist nur relevant für einen Fehler mit jQuery 1.5, wenn das Protokoll file: verwendet wird.

Ich hatte kürzlich ein ähnliches Problem beim Upgrade auf jQuery 1.5. Trotz einer korrekten Antwort wurde der Fehlerhandler ausgelöst. Ich habe es gelöst, indem ich das complete Ereignis verwendet und dann den Statuswert überprüft habe. z.B:

complete: function (xhr, status) {
    if (status === 'error' || !xhr.responseText) {
        handleError();
    }
    else {
        var data = xhr.responseText;
        //...
    }
}
Question

Ich habe versucht, einen "parsererror" von jquery für eine Ajax-Anfrage zu bekommen, ich habe versucht, den POST in einen GET zu ändern, indem ich die Daten auf verschiedene Arten zurückgebe (Klassen erstellen usw.), aber ich kann nicht herausfinden, was das Problem ist.

Mein Projekt ist in MVC3 und ich benutze jQuery 1.5 Ich habe ein Dropdown und auf dem onchange-Ereignis feuere ich einen Anruf ab, um einige Daten zu erhalten, die auf dem ausgewählt wurden, was ausgewählt wurde.

Dropdown: (lädt die "Views" aus der Liste in der Viewbag und das Feuern des Events funktioniert gut)

@{
    var viewHtmls = new Dictionary<string, object>();
    viewHtmls.Add("data-bind", "value: ViewID");
    viewHtmls.Add("onchange", "javascript:PageModel.LoadViewContentNames()");
}
@Html.DropDownList("view", (List<SelectListItem>)ViewBag.Views, viewHtmls)

Javascript:

this.LoadViewContentNames = function () {
    $.ajax({
        url: '/Admin/Ajax/GetViewContentNames',
        type: 'POST',
        dataType: 'json',
        data: { viewID: $("#view").val() },
        success: function (data) {
            alert(data);
        },
        error: function (data) {
            debugger;
            alert("Error");
        }
    });
};

Der obige Code ruft erfolgreich die MVC-Methode auf und gibt Folgendes zurück:

[{"ViewContentID":1,"Name":"TopContent","Note":"Content on the top"},
 {"ViewContentID":2,"Name":"BottomContent","Note":"Content on the bottom"}]

Aber jquery löst das Fehlerereignis für die $ .ajax () -Methode mit der Bezeichnung "parsererror" aus.




Sie sollten den dataType entfernen: "json". Dann sehen Sie die Magie ... der Grund dafür ist, dass Sie Json-Objekt in einfache Zeichenfolge konvertieren .. so JSON-Parser ist nicht in der Lage, diese Zeichenfolge zu analysieren, da kein JSON-Objekt.

this.LoadViewContentNames = function () {
$.ajax({
    url: '/Admin/Ajax/GetViewContentNames',
    type: 'POST',
    data: { viewID: $("#view").val() },
    success: function (data) {
        alert(data);
    },
    error: function (data) {
        debugger;
        alert("Error");
    }
 });
};



Sie haben die Ajax-Call-Antwort dataType wie folgt angegeben :

'json'

Wobei die tatsächliche Ajax-Antwort kein gültiger JSON ist und der JSON-Parser daher einen Fehler auslöst.

Der beste Ansatz, den ich empfehlen würde, ist das Ändern des Datentyps zu:

'Text'

und validieren Sie im Erfolgsrückruf, ob ein gültiger JSON zurückgegeben wird oder nicht, und wenn die JSON-Validierung fehlschlägt, warnen Sie sie auf dem Bildschirm, damit ersichtlich ist, zu welchem ​​Zweck der Ajax-Aufruf tatsächlich fehlschlägt. Schau dir das an:

$.ajax({
    url: '/Admin/Ajax/GetViewContentNames',
    type: 'POST',
    dataType: 'text',
    data: {viewID: $("#view").val()},
    success: function (data) {
        try {
            var output = JSON.parse(data);
            alert(output);
        } catch (e) {
            alert("Output is not valid JSON: " + data);
        }
    }, error: function (request, error) {
        alert("AJAX Call Error: " + error);
    }
});



Wenn Sie dataType: json nicht entfernen / ändern möchten , können Sie das strikte Parsing von jQuery überschreiben, indem Sie einen benutzerdefinierten converter :

$.ajax({
    // We're expecting a JSON response...
    dataType: 'json',

    // ...but we need to override jQuery's strict JSON parsing
    converters: {
        'text json': function(result) {
            try {
                // First try to use native browser parsing
                if (typeof JSON === 'object' && typeof JSON.parse === 'function') {
                    return JSON.parse(result);
                } else {
                    // Fallback to jQuery's parser
                    return $.parseJSON(result);
                }
            } catch (e) {
               // Whatever you want as your alternative behavior, goes here.
               // In this example, we send a warning to the console and return 
               // an empty JS object.
               console.log("Warning: Could not parse expected JSON response.");
               return {};
            }
        }
    },

    ...

Mit diesem können Sie das Verhalten anpassen, wenn die Antwort nicht als JSON geparst werden kann (auch wenn Sie einen leeren Antworttext erhalten!)

Mit diesem benutzerdefinierten Konverter wird .done() / success ausgelöst, solange die Anfrage ansonsten erfolgreich war (1xx oder 2xx Antwortcode).




Es gibt viele Vorschläge zum Entfernen

dataType: "json"

Während ich zugebe, dass dies funktioniert, ignoriert es das zugrunde liegende Problem. Wenn Sie sich sicher sind, dass die zurückgegebene Zeichenfolge wirklich JSON ist, suchen Sie zu Beginn der Antwort nach fehlendem Leerzeichen. Betrachten Sie es im Geiger. Meins sah so aus:

Connection: Keep-Alive
Content-Type: application/json; charset=utf-8

{"type":"scan","data":{"image":".\/output\/ou...

In meinem Fall war das ein Problem mit PHP, das unerwünschte Zeichen ausspuckte (in diesem Fall UTF-Datei-BOMs). Sobald ich diese entfernte, behob es das Problem, indem es auch behielt

dataType: json



Ich bekam auch "Request return with error: parser error". in der JavaScript-Konsole. In meinem Fall ging es nicht um Json, aber ich musste dem Ansichtstextbereich eine gültige Kodierung übergeben.

  String encodedString = getEncodedString(text, encoding);
  view.setTextAreaContent(encodedString);



Ich weiß nicht, ob das immer noch aktuell ist, aber das Problem war mit Encoding. Das Wechseln zu ANSI hat das Problem für mich gelöst.






Links