JQuery – Como fazer $ .post () usar contentType = application / json?

Eu tenho notado que ao usar $ .post () no jquery que o contentType padrão é application / x-www-form-urlencoded – quando meu código mvc asp.net precisa ter contentType = application / json

(Veja esta pergunta para o porque eu devo usar o aplicativo / json: ASPNET MVC – Por que é ModelState.IsValid false “O campo x é necessário” quando esse campo tem um valor? )

Como posso fazer $ .post () enviar contentType = application / json? Eu já tenho um grande número de funções $ .post (), então eu não quero mudar para $ .ajax () porque levaria muito tempo

Se eu tentar

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

Ainda tem contentType = application / x-www-form-urlencoded. Então, o que exatamente o “json” param faz se não mudar o contenttype para json?

Se eu tentar

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

Isso funciona, mas afeta todos os $ .get e $ .post que eu tenho e faz com que alguns quebrem.

Então, há alguma maneira que eu possa mudar o comportamento de $ .post () para enviar contentType = application / json?

Eu acho que você pode ter que

1.Modifique a fonte para fazer $ .post sempre usar o tipo de dados JSON, pois é apenas um atalho para uma $.ajax pré-configurada

Ou

2. Defina sua própria function de utilitário que é um atalho para a configuração $.ajax você deseja usar

Ou

3.Você poderia sobrescrever a $.post function com sua própria implementação através de correções de macacos.

O tipo de dados JSON no seu exemplo refere-se ao tipo de dados retornado do servidor e não ao formato enviado ao servidor.

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

Veja: jQuery.ajax ()

Finalmente encontrei a solução, que funciona para mim:

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

Acabei adicionando o seguinte método ao jQuery no meu 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 }); }; 

E para usá-lo

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

Isso foi feito simplesmente copiando o código de “get” e “post” das origens originais do JQuery e codificando alguns parâmetros para forçar um JSON POST.

Obrigado!

use apenas

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

ATUALIZADO @JK: Se você escrever na sua pergunta apenas um exemplo de código com $ .post, você encontrará um exemplo correspondente na resposta. Eu não quero repetir a mesma informação que você já estudou até saber: $ .post e $ .get são formas curtas de $ .ajax. Então, basta usar $ .ajax e você pode usar o conjunto completo de parâmetros sem ter que alterar as configurações globais.

A propósito, eu não recomendaria replace o padrão $ .post. É minha opinião pessoal , mas para mim é importante, não apenas que o programa funcione, mas também que todos os que lêem seu programa o entendam da mesma maneira. Sobrescrever methods padrão sem ter uma razão muito importante pode seguir para malentendidos na leitura do código do programa. Então eu repito minha recomendação mais uma vez: basta usar o formulário original $ .ajax jQuery em vez de jQuery.get e jQuery.post e você recebe programas que não apenas funcionam perfeitamente, mas podem ser lidos por pessoas sem nenhum mal-entendido.

O tipo de dados “json” que você pode passar como o último parâmetro para post () indica o tipo de dados que a function está esperando na resposta do servidor, não o tipo que está enviando na solicitação. Especificamente, define o header “Aceitar”.

Honestamente, sua melhor aposta é mudar para uma chamada ajax (). A function post () é usada como uma conveniência; uma versão simplificada da chamada ajax () quando você está apenas fazendo uma postagem de formulário simples. Você não é.

Se você realmente não quer mudar, você poderia fazer sua própria function chamada, digamos, xpost (), e simplesmente transformar os parâmetros dados em parâmetros para uma chamada jQuery ajax (), com o conjunto de tipo de conteúdo. Dessa forma, em vez de rewrite todas essas funções post () em funções ajax (), você só precisa alterá-las de post para xpost (ou qualquer outra coisa).

Eu sei que esta é uma resposta tardia, eu realmente tenho um método de atalho que eu uso para postagem / leitura de / para serviços baseados em MS .. ele funciona com MVC, bem como ASMX etc …

Usar:

 $.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: Eu também tenho um método JSON.parseAjax que é modificado a partir do arquivo JS do json.org, que adiciona manipulação para as datas MS “/Date(…)/” …

O arquivo json2.js modificado não é incluído, ele usa o analisador baseado em script no caso do IE8, pois há instâncias em que o analisador nativo é interrompido quando você estende o protótipo de matriz e / ou object, etc.

Eu estive pensando em renovar este código para implementar as interfaces de promises, mas funcionou muito bem para mim.

No centro da questão está o fato de que o JQuery no momento da escrita não tem um método postJSON enquanto o getJSON existe e faz a coisa certa.

um método postJSON faria o seguinte:

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

e pode ser usado assim:

 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 simples extensão da API jquery (de: https://benjamin-schweizer.de/jquerypostjson.html ) para $ .postJSON () faz o truque. Você pode usar postJSON () como todas as outras chamadas nativas de jquery Ajax. Você pode append manipuladores de events e assim por diante.

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

Como outras APIs do Ajax (como $ http do AngularJS), ele define o contentType correto como application / json. Você pode passar seus dados do json (objects javascript) diretamente, já que ele é stringificado aqui. O dataType retornado esperado é definido como JSON. Você pode append manipuladores de events padrão do jquery para promises, por exemplo:

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

Como sobre seu próprio adaptador / 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; } } })(); 

E uso extremamente simples:

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

A documentação atualmente mostra que, a partir de 3.0, $ .post aceitará o object settings, significando que você pode usar as opções $ .ajax. 3.0 ainda não foi lançado e no commit eles estão falando sobre esconder a referência a ele nos documentos, mas procure por ele no futuro!

Eu tive um problema semelhante com o seguinte código JavaScript:

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

Onde no Fiddler eu pude ver o pedido com:

  • Cabeçalho: Content-Type: application/x-www-form-urlencoded; charset=UTF-8 Content-Type: application/x-www-form-urlencoded; charset=UTF-8
  • Corpo: {"value":"5","maxValue":"5"}

Como resultado, meu servidor não pôde mapear um object para um tipo do lado do servidor.

Depois de mudar a última linha para esta:

 $.post(url, rating, showSavedNotification); 

No Fiddler eu ainda pude ver:

  • Cabeçalho: Content-Type: application/x-www-form-urlencoded; charset=UTF-8 Content-Type: application/x-www-form-urlencoded; charset=UTF-8
  • Corpo: value=5&maxValue=10

No entanto, o servidor começou a retornar o que eu esperava.

Por algum motivo, definir o tipo de conteúdo na solicitação do ajax como @Adrien sugerido não funcionou no meu caso. No entanto, você pode alterar o tipo de conteúdo usando $ .post fazendo isso antes:

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

Então faça sua chamada $.post :

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

Eu tive problemas com o jQuery + IIS, e essa foi a única solução que ajudou o jQuery a entender o uso da codificação windows-1252 para solicitações ajax.

podemos mudar o tipo de conteúdo assim em $ .post

$ .post (url, dados, function (dados, status, xhr) {xhr.setRequestHeader (“Tipo de conteúdo”, “aplicativo / x-www-formulário-urlencoded; charset = utf-8”);});

Você não pode enviar diretamente o application/json – ele precisa ser um parâmetro de uma solicitação GET / POST.

Então, algo como

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