Jquery -如何使$.post()使用contentType=应用程序/json?

我注意到,在jquery中使用$.post()时,默认的内容类型是application/x-www-form-urlencoded -当我的asp.net mvc代码需要有contentType=application/json

(见这个问题为什么我必须使用application/json: ASPNET MVC -为什么是ModelState。is valid false " x字段是必需的"当该字段有值时?)

我怎么能让$.post()发送contentType=应用程序/json?我已经有了大量的$.post()函数,所以我不想更改为$.ajax(),因为这会花费太多时间

如果我尝试

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

它仍然有contentType=application/x-www-form-urlencoded。那么,如果“json”参数没有将内容类型更改为json,它究竟做了什么呢?

如果我尝试

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

这是可行的,但影响到每一美元。Get和$。帖子,我有和导致一些打破。

那么是否有一些方法,我可以改变$.post()的行为发送contentType=application/json?

457267 次浏览

我想你可能不得不这么做

1.将源代码修改为$。post总是使用JSON数据类型,因为它实际上只是一个预先配置的$.ajax调用的快捷方式

2. __abc1

3.你可以通过monkey补丁用你自己的实现覆盖$.post function

示例中的JSON数据类型指的是返回给服务器的数据类型,而不是返回给服务器的格式发送

你不能直接发送application/json——它必须是GET/POST请求的参数。

就像这样

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

只使用

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

更新 @JK:如果你在你的问题中只写一个代码示例和$。你在答案中找到一个相应的例子。我不想重复同样的信息,你已经学习了,直到知道:$。Post和$。Get是$.ajax的缩写形式。所以只需使用$。Ajax,您可以使用它的全部参数集,而无需更改任何全局设置。

顺便说一下,我不建议覆盖标准的$.post。它是我个人的看法,但对我来说,这很重要,不仅是程序工作,而且所有阅读你的程序的人都以同样的方式理解它。重写标准方法没有很重要的原因可以跟随到程序代码的阅读误区。所以我再次重复我的建议:只使用原来的$。ajax形式的jQuery而不是jQuery.getjQuery.post和你收到的程序,不仅完美的工作,但可以阅读的人没有任何误解。

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

参见:jQuery.ajax ()

可以作为最后一个参数传递给post()的“json”数据类型表示函数在服务器响应中期望的数据类型,而不是它在请求中发送的数据类型。具体来说,它设置了“Accept”报头。

老实说,最好的办法是切换到ajax()调用。post()函数是为了方便;ajax()的简化版本,当您只是做一个简单的表单发布时调用。你不是。

如果真的不想切换,可以创建自己的函数,比如xpost(),并使用内容类型设置将给定的参数转换为jQuery ajax()调用的参数。这样,就不必将所有这些post()函数重写为ajax()函数,只需将它们全部从post更改为xpost(或其他)。

最后我找到了适合我的解决方案:

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

我知道这是一个晚的答案,我实际上有一个快捷的方法,我用来发布/读取/从基于MS的服务。它与MVC以及ASMX等工作…

使用:

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

注意:我还有一个JSON。parseAjax方法是修改自json.org的JS文件,它增加了处理MS“/Date(…)/”日期…

修改后的json2.js文件不包括在内,它在IE8的情况下使用基于脚本的解析器,因为当你扩展数组和/或对象的原型时,本地解析器会中断,等等。

我一直在考虑修改这段代码以实现承诺接口,但它对我来说工作得非常好。

我最终在我的脚本中添加了以下方法:

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

然后使用它

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

这是通过简单地从原始JQuery源代码中复制“get”和“post”的代码并硬编码一些参数来强制JSON post来实现的。

谢谢!

问题的核心是,在编写本文时,JQuery还没有postJSON方法,而getJSON存在并做正确的事情。

postJSON方法会做以下事情:

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

并且可以这样使用:

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

那么您自己的适配器/包装器呢?

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

用法极其简单:

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

文档当前显示,从3.0开始,$。Post将接受Settings对象,这意味着您可以使用$。ajax选项。3.0还没有发布,提交时他们正在讨论在文档中隐藏对它的引用,但在未来寻找它!

我有类似的问题与以下JavaScript代码:

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


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


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

提琴手中,我可以看到请求:

  • 标题:Content-Type: application/x-www-form-urlencoded; charset=UTF-8
  • 身体:{"value":"5","maxValue":"5"}

因此,我的服务器无法将对象映射到服务器端类型。

把最后一行改成这样:

$.post(url, rating, showSavedNotification);

在《提琴手》里我还能看到:

  • 标题:Content-Type: application/x-www-form-urlencoded; charset=UTF-8
  • 身体:value=5&maxValue=10

然而,服务器开始返回我所期望的结果。

出于某种原因,在ajax请求上设置@Adrien建议的内容类型在我的情况下不起作用。但是,您实际上可以使用$更改内容类型。在发布之前这样做:

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

然后调用$.post:

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

我有jQuery + IIS的问题,这是唯一的解决方案,帮助jQuery理解使用windows-1252编码ajax请求。

这个简单的jquery API扩展(from: https://benjamin-schweizer.de/jquerypostjson.html)为$. postjson()做的技巧。您可以像使用其他原生jquery Ajax调用一样使用postJSON()。您可以附加事件处理程序等等。

$.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
});
};
像其他Ajax api(如AngularJS中的$http)一样,它将正确的内容类型设置为application/json。 你可以直接传递json数据(javascript对象),因为它在这里被字符串化了。 预期返回的数据类型被设置为JSON。 你可以为承诺附加jquery的默认事件处理程序,例如:

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

我们可以在$.post中像这样更改Content-type

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

$.post不工作,如果你有CORS(跨起源资源共享)问题。尝试以以下格式使用$.ajax:

$.ajax({
url: someurl,
contentType: 'application/json',
data: requestInJSONFormat,
headers: { 'Access-Control-Allow-Origin': '*' },
dataType: 'json',
type: 'POST',
async: false,
success: function (Data) {...}
});

你猜怎么着?@BenCreasy完全正确!!

从jQuery的版本1.12.0开始,我们可以这样做:

$.post({
url: yourURL,
data: yourData,
contentType: 'application/json; charset=utf-8'
})
.done(function (response) {
//Do something on success response...
});

我刚刚测试了一下,它工作了!!