Jquery: cómo hacer que $ .post () use contentType = application / json?

Me he dado cuenta de que al usar $ .post () en jquery que el contentType predeterminado es application / x-www-form-urlencoded, cuando mi código asp.net mvc necesita tener contentType = application / json

(Consulte esta pregunta para saber por qué debo usar application / json: ASPNET MVC – ¿Por qué es ModelState.IsValid false “El campo x es obligatorio” cuando ese campo tiene un valor? )

¿Cómo puedo hacer que $ .post () envíe contentType = application / json? Ya tengo una gran cantidad de funciones $ .post (), así que no quiero cambiar a $ .ajax () porque tomaría demasiado tiempo

Si bash

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

Todavía tiene contentType = application / x-www-form-urlencoded. Entonces, ¿qué hace exactamente el parametro “json” si no cambia el tipo de contenido a json?

Si bash

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

Eso funciona pero afecta cada $ .get y $ .post que tengo y hace que algunos se rompan.

Entonces, ¿hay alguna forma de que pueda cambiar el comportamiento de $ .post () para enviar contentType = application / json?

Creo que deberás

1. Modifique la fuente para hacer que $ .post siempre use el tipo de datos JSON, ya que es solo un atajo para una llamada $.ajax preconfigurada.

O

2. Defina su propia función de utilidad que es un acceso directo para la configuración de $.ajax que desea usar

O

3.Puede sobrescribir la $.post function con su propia implementación a través de parche de mono.

El tipo de datos JSON en su ejemplo se refiere al tipo de datos devuelto por el servidor y no al formato enviado al servidor.

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

Ver: jQuery.ajax ()

Finalmente encontré la solución, que funciona para mí:

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

Terminé agregando el siguiente método a jQuery en mi script:

 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 }); }; 

Y para usarlo

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

Esto se hizo simplemente copiando el código de “get” y “post” de las fonts originales de JQuery y codificando algunos parámetros para forzar un JSON POST.

¡Gracias!

usar solo

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

ACTUALIZADO @JK: Si escribe en su pregunta un solo ejemplo de código con $ .post, encontrará un ejemplo correspondiente en la respuesta. No quiero repetir la misma información que ya estudió hasta saber: $ .post y $ .get son formas cortas de $ .ajax. Así que solo use $ .ajax y puede usar el conjunto completo de sus parámetros sin tener que cambiar ninguna configuración global.

Por cierto, no recomendaría sobreescribir el $ .post estándar. Es mi opinión personal , pero para mí es importante, no solo que el progtwig funcione, sino también que todos los que lean su progtwig lo entiendan de la misma manera. Sobrescribir los métodos estándar sin tener una razón muy importante puede dar lugar a malentendidos en la lectura del código del progtwig. Así que repito mi recomendación una vez más: solo use el formulario original $ .ajax jQuery en lugar de jQuery.get y jQuery.post y recibirá progtwigs que no solo funcionan perfectamente, sino que también pueden ser leídos por personas sin malentendidos.

El tipo de datos “json” que puede pasar como el último parámetro para publicar () indica qué tipo de datos espera la función en la respuesta del servidor, no qué tipo está enviando en la solicitud. Específicamente establece el encabezado “Aceptar”.

Honestamente, su mejor opción es cambiar a una llamada ajax (). La función post () se entiende como una conveniencia; una versión simplificada de la llamada ajax () cuando solo estás haciendo una publicación de formulario simple. Usted no es.

Si realmente no desea cambiar, podría hacer su propia función llamada, digamos, xpost (), y simplemente transformar los parámetros dados en parámetros para una llamada jQuery ajax (), con el conjunto de tipo de contenido. De esta forma, en lugar de reescribir todas esas funciones de post () en funciones ajax (), solo tiene que cambiarlas todas de la publicación a xpost (o lo que sea).

Sé que esta es una respuesta tardía, en realidad tengo un método abreviado que uso para publicar / leer desde / hacia servicios basados ​​en MS … funciona con MVC, ASMX, etc.

Utilizar:

 $.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)); 

NOTA: También tengo un método JSON.parseAjax que se modifica desde el archivo JS de json.org, que agrega manejo para las fechas MS “/Date(..)/”.

El archivo json2.js modificado no está incluido; utiliza el analizador basado en scripts en el caso de IE8, ya que hay instancias donde el analizador nativo se rompe cuando extiende el prototipo de matriz y / u objeto, etc.

He estado considerando renovar este código para implementar las interfaces de promesas, pero funcionó muy bien para mí.

En el centro del asunto está el hecho de que JQuery en el momento de escribir no tiene un método postJSON mientras que getJSON existe y hace lo correcto.

un método postJSON haría lo siguiente:

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

y puede usarse así:

 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 }); 

Esta simple extensión de jquery API (desde: https://benjamin-schweizer.de/jquerypostjson.html ) para $ .postJSON () hace el truco. Puede usar postJSON () como cualquier otra llamada jquery Ajax nativa. Puede adjuntar controladores de eventos, etc.

 $.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 }); }; 

Al igual que otras API de Ajax (como $ http de AngularJS), establece el contentType correcto para application / json. Puede pasar sus datos json (objetos javascript) directamente, ya que aquí se codifica. El tipo de datos esperado devuelto se establece en JSON. Puede adjuntar manejadores de eventos predeterminados de jquery para promesas, por ejemplo:

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

¿Qué hay de su propio adaptador / envoltura?

 //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; } } })(); 

Y un uso extremadamente simple:

 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... } }); 

La documentación muestra actualmente que a partir de 3.0, $ .post aceptará el objeto de configuración, lo que significa que puede usar las opciones de $ .ajax. 3.0 aún no se ha lanzado y en el compromiso están hablando de ocultar la referencia en los documentos, ¡pero búscalo en el futuro!

Tuve un problema similar con el siguiente código JavaScript:

 var url = 'http://my-host-name.com/api/Rating'; var rating = { value: 5, maxValue: 10 }; $.post(url, JSON.stringify(rating), showSavedNotification); 

Donde en el Fiddler pude ver la solicitud con:

  • Encabezado: Content-Type: application/x-www-form-urlencoded; charset=UTF-8 Content-Type: application/x-www-form-urlencoded; charset=UTF-8
  • Cuerpo: {"value":"5","maxValue":"5"}

Como resultado, mi servidor no pudo asignar un objeto a un tipo de servidor.

Después de cambiar la última línea a esta:

 $.post(url, rating, showSavedNotification); 

En el Fiddler todavía podía ver:

  • Encabezado: Content-Type: application/x-www-form-urlencoded; charset=UTF-8 Content-Type: application/x-www-form-urlencoded; charset=UTF-8
  • Cuerpo: value=5&maxValue=10

Sin embargo, el servidor comenzó a devolver lo que esperaba.

Por alguna razón, la configuración del tipo de contenido en la solicitud de Ajax como @Adrien sugirió que no funcionó en mi caso. Sin embargo, puedes cambiar el tipo de contenido usando $ .post haciendo esto antes:

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

Luego haga su llamada a $.post :

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

Tuve un problema con jQuery + IIS, y esta fue la única solución que ayudó a jQuery a entender el uso de la encoding windows-1252 para las solicitudes ajax.

podemos cambiar el tipo de contenido como este en $ .post

$ .post (url, data, function (data, status, xhr) {xhr.setRequestHeader (“Content-type”, “application / x-www-form-urlencoded; charset = utf-8”);});

No puede enviar application/json directamente; tiene que ser un parámetro de una solicitud GET / POST.

Así que algo así como

 $.post(url, {json: "...json..."}, function());