it-swarm.com.de

JQuery - Wie kann man $ .post () dazu bringen, contentType = application / json zu verwenden?

Ich habe festgestellt, dass bei der Verwendung von $ .post () in jquery der standardmäßige contentType application/x-www-form-urlencoded lautet - wenn mein asp.net-MVC-Code contentType = application/json haben muss

(In dieser Frage erfahren Sie, warum ich application/json verwenden muss: ASPNET MVC - Warum ist ModelState.IsValid false? "Das x-Feld ist erforderlich", wenn dieses Feld einen Wert enthält? )

Wie kann ich dafür sorgen, dass $ .post () contentType = application/json sendet? Ich habe bereits eine große Anzahl von $ .post () - Funktionen, daher möchte ich nicht zu $ ​​.ajax () wechseln, da dies zu lange dauern würde

Wenn ich es versuche

$.post(url, data, function(), "json") 

Es hat immer noch contentType = application/x-www-form-urlencoded. Was genau macht der Parameter "json", wenn er den Inhaltstyp nicht in json ändert?

Wenn ich es versuche

$.ajaxSetup({
  contentType: "application/json; charset=utf-8"
});

Das funktioniert, wirkt sich aber auf jedes einzelne $ .get und $ .post aus, die ich habe, und bewirkt, dass einige brechen.

Gibt es also eine Möglichkeit, das Verhalten von $ .post () so zu ändern, dass contentType = application/json gesendet wird?

284
JK.

Ich denke, du musst vielleicht

1.Modifizieren Sie die Quelle, damit $ .post immer den JSON-Datentyp verwendet, da dies nur eine Verknüpfung für einen vorkonfigurierten $.ajax - Aufruf ist

Oder

2. Definieren Sie Ihre eigene Utility-Funktion, die eine Verknüpfung für die $.ajax - Konfiguration darstellt, die Sie verwenden möchten.

Oder

3.Sie können den $.post function Mit Ihrer eigenen Implementierung per Affen-Patching überschreiben.

Der JSON-Datentyp in Ihrem Beispiel bezieht sich auf den zurückgegebenen Datentyp from the server und nicht auf das Format sent to the server.

67
Russ Cam
$.ajax({
  url:url,
  type:"POST",
  data:data,
  contentType:"application/json; charset=utf-8",
  dataType:"json",
  success: function(){
    ...
  }
})

Siehe: jQuery.ajax ()

371
Adrien

Endlich habe ich die Lösung gefunden, die für mich funktioniert:

jQuery.ajax ({
    url: myurl,
    type: "POST",
    data: JSON.stringify({data:"test"}),
    dataType: "json",
    contentType: "application/json; charset=utf-8",
    success: function(){
        //
    }
});
79

Am Ende habe ich die folgende Methode zu jQuery in meinem Skript hinzugefügt:

jQuery["postJSON"] = function( url, data, callback ) {
    // shift arguments if data argument was omitted
    if ( jQuery.isFunction( data ) ) {
        callback = data;
        data = undefined;
    }

    return jQuery.ajax({
        url: url,
        type: "POST",
        contentType:"application/json; charset=utf-8",
        dataType: "json",
        data: data,
        success: callback
    });
};

Und es zu benutzen

$.postJSON('http://url', {data: 'goes', here: 'yey'}, function (data, status, xhr) {
    alert('Nailed it!')
});

Dazu wurde einfach der Code von "get" und "post" aus den ursprünglichen JQuery-Quellen kopiert und einige Parameter hartcodiert, um einen JSON-POST zu erzwingen.

Vielen Dank!

41
kontinuity

benutze einfach

jQuery.ajax ({
    url: myurl,
    type: "POST",
    data: mydata,
    dataType: "json",
    contentType: "application/json; charset=utf-8",
    success: function(){
        //
    }
});

AKTUALISIERT @JK: Wenn Sie nur in Ihre Frage schreiben ein Codebeispiel mit $ .post finden Sie ein entsprechendes Beispiel in der Antwort . Ich möchte nicht die gleichen Informationen wiederholen, die Sie bereits studiert haben, bis Sie wissen: $ .post und $ .get sind Kurzformen von $ .ajax. Verwenden Sie also einfach $ .ajax und Sie können den gesamten Parametersatz verwenden, ohne die globalen Einstellungen ändern zu müssen.

Übrigens würde ich nicht empfehlen, den Standard $ .post zu überschreiben. Es ist meine persönliche Meinung , aber für mich ist es nicht nur wichtig, dass das Programm funktioniert, sondern dass alle, die Ihr Programm lesen, es auf die gleiche Weise verstehen . Das Überschreiben von Standardmethoden ohne einen sehr wichtigen Grund kann auf Missverständnis beim Lesen des Programmcodes folgen. Also wiederhole ich noch einmal meine Empfehlung: Verwende einfach das ursprüngliche $ .ajax-Formular jQuery anstelle von jQuery.get und jQuery.post und Sie erhalten Programme, die nicht nur einwandfrei funktionieren, sondern auch von Menschen ohne Missverständnisse gelesen werden können.

20
Oleg

Der "json" -Datentyp, den Sie als letzten Parameter für post () übergeben können, gibt an, welchen Datentyp die Funktion in der Antwort des Servers erwartet, und nicht, welchen Typ sie in der Anforderung sendet. Insbesondere wird der Header "Accept" gesetzt.

Ehrlich gesagt ist es am besten, zu einem ajax () -Anruf zu wechseln. Die post () - Funktion ist als Annehmlichkeit gedacht. Eine vereinfachte Version des Aufrufs ajax () für den Fall, dass Sie nur ein einfaches Formular veröffentlichen. Sie sind nicht.

Wenn Sie wirklich nicht wechseln möchten, können Sie eine eigene Funktion mit dem Namen xpost () erstellen und die angegebenen Parameter einfach in Parameter für einen Aufruf von jQuery ajax () mit dem Inhaltstyp set umwandeln. Auf diese Weise müssen Sie nicht alle post () -Funktionen in ajax () -Funktionen umschreiben, sondern alle von post in xpost (oder was auch immer) ändern.

8
Jacob Mattison

Ich weiß, dass dies eine späte Antwort ist. Ich habe tatsächlich eine Verknüpfungsmethode, die ich zum Posten/Lesen zu/von MS-basierten Diensten verwende. Sie funktioniert sowohl mit MVC als auch mit ASMX usw.

Verwenden:

$.msajax(
  '/services/someservice.asmx/SomeMethod'
  ,{}  /*empty object for nothing, or object to send as Application/JSON */
  ,function(data,jqXHR) {
    //use the data from the response.
  }
  ,function(err,jqXHR) {
    //additional error handling.
  }
);
//sends a json request to an ASMX or WCF service configured to reply to JSON requests.
(function ($) {
  var tries = 0; //IE9 seems to error out the first ajax call sometimes... will retry up to 5 times

  $.msajax = function (url, data, onSuccess, onError) {
    return $.ajax({
      'type': "POST"
      , 'url': url
      , 'contentType': "application/json"
      , 'dataType': "json"
      , 'data': typeof data == "string" ? data : JSON.stringify(data || {})
      ,beforeSend: function(jqXHR) {
        jqXHR.setRequestHeader("X-MicrosoftAjax","Delta=true");
      }
      , 'complete': function(jqXHR, textStatus) {
        handleResponse(jqXHR, textStatus, onSuccess, onError, function(){
          setTimeout(function(){
            $.msajax(url, data, onSuccess, onError);
          }, 100 * tries); //try again
        });
      }
    });
  }

  $.msajax.defaultErrorMessage = "Error retreiving data.";


  function logError(err, errorHandler, jqXHR) {
    tries = 0; //reset counter - handling error response

    //normalize error message
    if (typeof err == "string") err = { 'Message': err };

    if (console && console.debug && console.dir) {
      console.debug("ERROR processing jQuery.msajax request.");
      console.dir({ 'details': { 'error': err, 'jqXHR':jqXHR } });
    }

    try {
      errorHandler(err, jqXHR);
    } catch (e) {}
    return;
  }


  function handleResponse(jqXHR, textStatus, onSuccess, onError, onRetry) {
    var ret = null;
    var reterr = null;
    try {
      //error from jqXHR
      if (textStatus == "error") {
        var errmsg = $.msajax.defaultErrorMessage || "Error retreiving data.";

        //check for error response from the server
        if (jqXHR.status >= 300 && jqXHR.status < 600) {
          return logError( jqXHR.statusText || msg, onError, jqXHR);
        }

        if (tries++ < 5) return onRetry();

        return logError( msg, onError, jqXHR);
      }

      //not an error response, reset try counter
      tries = 0;

      //check for a redirect from server (usually authentication token expiration).
      if (jqXHR.responseText.indexOf("|pageRedirect||") > 0) {
        location.href = decodeURIComponent(jqXHR.responseText.split("|pageRedirect||")[1].split("|")[0]).split('?')[0];
        return;
      }

      //parse response using ajax enabled parser (if available)
      ret = ((JSON && JSON.parseAjax) || $.parseJSON)(jqXHR.responseText);

      //invalid response
      if (!ret) throw jqXHR.responseText;  

      // d property wrap as of .Net 3.5
      if (ret.d) ret = ret.d;

      //has an error
      reterr = (ret && (ret.error || ret.Error)) || null; //specifically returned an "error"

      if (ret && ret.ExceptionType) { //Microsoft Webservice Exception Response
        reterr = ret
      }

    } catch (err) {
      reterr = {
        'Message': $.msajax.defaultErrorMessage || "Error retreiving data."
        ,'debug': err
      }
    }

    //perform final logic outside try/catch, was catching error in onSuccess/onError callbacks
    if (reterr) {
      logError(reterr, onError, jqXHR);
      return;
    }

    onSuccess(ret, jqXHR);
  }

} (jQuery));

ANMERKUNG: Ich habe auch eine JSON.parseAjax-Methode, die aus der JS-Datei von json.org modifiziert wurde und die die Behandlung der MS-Daten "/Date(...)/" hinzufügt.

Die geänderte Datei json2.js ist nicht enthalten. Sie verwendet im Fall von IE8 den skriptbasierten Parser, da es Fälle gibt, in denen der systemeigene Parser unterbrochen wird, wenn Sie den Prototyp eines Arrays und/oder Objekts erweitern.

Ich habe überlegt, diesen Code zu überarbeiten, um die versprochenen Schnittstellen zu implementieren, aber es hat für mich wirklich gut funktioniert.

5
Tracker1

Der Kern der Sache ist die Tatsache, dass JQuery zum Zeitpunkt des Schreibens keine postJSON-Methode hat, während getJSON existiert und das Richtige tut.

eine postJSON-Methode würde Folgendes ausführen:

postJSON = function(url,data){
    return $.ajax({url:url,data:JSON.stringify(data),type:'POST', contentType:'application/json'});
};

und kann so verwendet werden:

postJSON( 'path/to/server', my_JS_Object_or_Array )
    .done(function (data) {
        //do something useful with server returned data
        console.log(data);
    })
    .fail(function (response, status) {
        //handle error response
    })
    .always(function(){  
      //do something useful in either case
      //like remove the spinner
    });
4
dbrin

Diese einfache jquery-API-Erweiterung (von: https://benjamin-schweizer.de/jquerypostjson.html ) für $ .postJSON () macht den Trick. Sie können postJSON () wie jeden anderen nativen Ajax-Aufruf von jquery verwenden. Sie können Ereignishandler usw. anhängen.

$.postJSON = function(url, data, callback) {
  return jQuery.ajax({
    'type': 'POST',
    'url': url,
    'contentType': 'application/json; charset=utf-8',
    'data': JSON.stringify(data),
    'dataType': 'json',
    'success': callback
  });
};

Wie andere Ajax-APIs (wie $ http von AngularJS) setzt es den richtigen contentType auf application/json. Sie können Ihre json-Daten (Javascript-Objekte) direkt weitergeben, da sie hier stringifiziert werden. Der erwartete zurückgegebene Datentyp ist auf JSON festgelegt. Sie können die Standardereignishandler von jquery für Versprechungen anfügen, zum Beispiel:

$.postJSON(apiURL, jsonData)
 .fail(function(res) {
   console.error(res.responseText);
 })
 .always(function() {
   console.log("FINISHED ajax post, hide the loading throbber");
 });
2
Ruwen

Die Dokumentation zeigt derzeit, dass $ .post ab 3.0 das Einstellungsobjekt akzeptiert, dh, Sie können die $ .ajax-Optionen verwenden. 3.0 ist noch nicht veröffentlicht und auf dem Commit sie reden darüber, den Verweis darauf in den Dokumenten zu verbergen, aber suchen Sie danach in der Zukunft!

1
Ben Creasy

Ich hatte ein ähnliches Problem mit dem folgenden JavaScript-Code:

var url = 'http://my-Host-name.com/api/Rating';

var rating = { 
  value: 5,
  maxValue: 10
};

$.post(url, JSON.stringify(rating), showSavedNotification);

Wo im Fiddler konnte ich die Anfrage sehen mit:

  • Header: Content-Type: application/x-www-form-urlencoded; charset=UTF-8
  • Körper: {"value":"5","maxValue":"5"}

Infolgedessen konnte mein Server ein Objekt keinem serverseitigen Typ zuordnen.

Nachdem Sie die letzte Zeile in diese geändert haben:

$.post(url, rating, showSavedNotification);

Im Fiddler konnte ich noch sehen:

  • Header: Content-Type: application/x-www-form-urlencoded; charset=UTF-8
  • Körper: value=5&maxValue=10

Der Server hat jedoch die erwarteten Werte zurückgegeben.

1
Oleg Burov

Wie wäre es mit Ihrem eigenen Adapter/Wrapper?

//adapter.js
var adapter = (function() {

return {

    post: function (url, params) {
        adapter.ajax(url, "post", params);
        },
    get: function (url, params) {
        adapter.ajax(url, "get", params);
    },
    put: function (url, params) {
        adapter.ajax(url, "put", params);
    },
    delete: function (url, params) {
        adapter.ajax(url, "delete", params);
    },
    ajax: function (url, type, params) {
        var ajaxOptions = {
            type: type.toUpperCase(),
            url: url,
            success: function (data, status) {
                var msgType = "";
                // checkStatus here if you haven't include data.success = true in your
                // response object
                if ((params.checkStatus && status) || 
                   (data.success && data.success == true)) {
                            msgType = "success";
                            params.onSuccess && params.onSuccess(data);
                    } else {
                            msgType = "danger";
                            params.onError && params.onError(data);
                    }
            },
            error: function (xhr) {
                    params.onXHRError && params.onXHRError();
                    //api.showNotificationWindow(xhr.statusText, "danger");
            }
        };
        if (params.data) ajaxOptions.data = params.data;
        if (api.isJSON(params.data)) {
            ajaxOptions.contentType = "application/json; charset=utf-8";
            ajaxOptions.dataType = "json";
        }
        $.ajax($.extend(ajaxOptions, params.options));
    }
})();

    //api.js
var api = {
  return {
    isJSON: function (json) {
        try {
            var o = JSON.parse(json);
            if (o && typeof o === "object" && o !== null) return true;
        } catch (e) {}
        return false;
    }
  }
})();

Und extrem einfache Bedienung:

adapter.post("where/to/go", {
    data: JSON.stringify(params),
    onSuccess: function (data) {
        //on success response...
    }
    //, onError: function(data) {  //on error response... }
    //, onXHRError: function(xhr) {  //on XHR error response... }
});
0
Blackening

Aus irgendeinem Grund funktionierte es in meinem Fall nicht, den Inhaltstyp für die Ajax-Anforderung auf @Adrien festzulegen. Sie können den Inhaltstyp jedoch mithilfe von "$ .post" ändern, indem Sie Folgendes ausführen:

$.ajaxSetup({
    'beforeSend' : function(xhr) {
        xhr.overrideMimeType('application/json; charset=utf-8');
    },
});

Dann mach dein $.post Anruf:

$.post(url, data, function(), "json")

Ich hatte Probleme mit jQuery + IIS, und dies war die einzige Lösung, die es jQuery ermöglichte, die Windows-1252-Codierung für Ajax-Anforderungen zu verwenden.

0
Johannes