Jquery - 如何让 $.post() 使用 contentType=application/json?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/2845459/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Jquery - How to make $.post() use contentType=application/json?
提问by JK.
I've noticed that when using $.post() in jquery that the default contentType is application/x-www-form-urlencoded - when my asp.net mvc code needs to have contentType=application/json
我注意到在 jquery 中使用 $.post() 时默认的 contentType 是 application/x-www-form-urlencoded - 当我的 asp.net mvc 代码需要 contentType=application/json
(See this question for why I must use application/json: ASPNET MVC - Why is ModelState.IsValid false "The x field is required" when that field does have a value?)
(有关为什么我必须使用 application/json,请参阅此问题:ASPNET MVC - Why is ModelState.IsValid false "The x field is required" when that field does have a value?)
How can I make $.post() send contentType=application/json? I already have a large number of $.post() functions, so I don't want to change to $.ajax() because it would take too much time
如何让 $.post() 发送 contentType=application/json?我已经有大量的 $.post() 函数了,所以不想改成 $.ajax() 因为太费时间了
If I try
如果我尝试
$.post(url, data, function(), "json")
It still has contentType=application/x-www-form-urlencoded. So what exactly does the "json" param do if it does not change the contenttype to json?
它仍然具有 contentType=application/x-www-form-urlencoded。那么,如果“json”参数不将内容类型更改为 json,它究竟会做什么?
If I try
如果我尝试
$.ajaxSetup({
contentType: "application/json; charset=utf-8"
});
That works but affects every single $.get and $.post that I have and causes some to break.
这有效但会影响我拥有的每一个 $.get 和 $.post 并导致一些中断。
So is there some way that I can change the behavior of $.post() to send contentType=application/json?
那么有什么方法可以改变 $.post() 的行为来发送 contentType=application/json 吗?
采纳答案by Russ Cam
I think you may have to
我想你可能不得不
1.Modify the source to make $.post always use JSON data type as it really is just a shortcut for a pre configured $.ajax
call
1.修改源代码使$.post始终使用JSON数据类型,因为它实际上只是预配置$.ajax
调用的快捷方式
Or
或者
2.Define your own utility function that is a shortcut for the $.ajax
configuration you want to use
2.定义您自己的实用程序功能,这是$.ajax
您要使用的配置的快捷方式
Or
或者
3.You could overwrite the $.post function
with your own implementation via monkey patching.
3.$.post function
您可以通过猴子补丁用您自己的实现覆盖。
The JSON datatype in your example refers to the datatype returned fromthe server and not the format sentto the server.
您示例中的 JSON 数据类型是指从服务器返回的数据类型,而不是发送到服务器的格式。
回答by Adrien
$.ajax({
url:url,
type:"POST",
data:data,
contentType:"application/json; charset=utf-8",
dataType:"json",
success: function(){
...
}
})
See : jQuery.ajax()
请参阅:jQuery.ajax()
回答by vvkatwss vvkatwss
Finally I found the solution, that works for me:
最后我找到了对我有用的解决方案:
jQuery.ajax ({
url: myurl,
type: "POST",
data: JSON.stringify({data:"test"}),
dataType: "json",
contentType: "application/json; charset=utf-8",
success: function(){
//
}
});
回答by kontinuity
I ended up adding the following method to jQuery in my script:
我最终在我的脚本中向 jQuery 添加了以下方法:
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
});
};
And to use it
并使用它
$.postJSON('http://url', {data: 'goes', here: 'yey'}, function (data, status, xhr) {
alert('Nailed it!')
});
This was done by simply copying the code of "get" and "post" from the original JQuery sources and hardcoding a few parameters to force a JSON POST.
这是通过简单地从原始 JQuery 源复制“get”和“post”代码并硬编码一些参数以强制 JSON POST 来完成的。
Thanks!
谢谢!
回答by Oleg
use just
只用
jQuery.ajax ({
url: myurl,
type: "POST",
data: mydata,
dataType: "json",
contentType: "application/json; charset=utf-8",
success: function(){
//
}
});
UPDATED@JK: If you write in your question only one code examplewith $.post you find one corresponding example in the answer. I don't want to repeat the same information which you already studied till know: $.post and $.get are short forms of $.ajax. So just use $.ajax and you can use the full set of it's parameters without having to change any global settings.
更新@JK:如果您在问题中只用 $.post写了一个代码示例,您会在答案中找到一个相应的示例。我不想重复你已经学习过的相同信息,直到知道:$.post 和 $.get 是 $.ajax 的缩写形式。所以只需使用 $.ajax 就可以使用它的全部参数集,而无需更改任何全局设置。
By the way I wouldn't recommend overwriting the standard $.post. It's my personal opinion, but for me it's important, not only that the program works, but also that all who read your program understand it with the same way. Overwriting standard methods without having a very important reasoncan follow to misunderstanding in readingof the program code. So I repeat my recommendation one more time: just use the original $.ajax form jQuery instead of jQuery.get
and jQuery.post
and you receive programs which not only perfectly work, but can be read by people without any misunderstandings.
顺便说一句,我不建议覆盖标准的 $.post。这是我个人的意见,但对我来说很重要,不仅程序有效,而且所有阅读您程序的人都以相同的方式理解它。在没有非常重要的原因的情况下覆盖标准方法可能会导致在阅读程序代码时产生误解。所以我再重复一次我的建议:只需使用原始的 $.ajax 形式的 jQuery 而不是jQuery.get
and jQuery.post
,您将收到不仅可以完美运行,而且可以被人们阅读而不会产生任何误解的程序。
回答by Jacob Mattison
The "json" datatype that you can pass as the last parameter to post() indicates what type of data the function is expecting in the server's response, not what type it's sending in the request. Specifically it sets the "Accept" header.
您可以作为最后一个参数传递给 post() 的“json”数据类型表示该函数在服务器响应中期望的数据类型,而不是它在请求中发送的数据类型。具体来说,它设置“接受”标头。
Honestly your best bet is to switch to an ajax() call. The post() function is meant as a convenience; a simplified version of the ajax() call for when you are just doing a simple form posting. You aren't.
老实说,您最好的选择是切换到 ajax() 调用。post() 函数是为了方便;当你只是做一个简单的表单发布时,ajax() 调用的简化版本。你不是。
If you really don't want to switch, you could make your own function called, say, xpost(), and have it simply transform the given parameters into parameters for a jQuery ajax() call, with the content-type set. That way, rather than rewriting all of those post() functions into ajax() functions, you just have to change them all from post to xpost (or whatever).
如果您真的不想切换,您可以调用自己的函数,例如 xpost(),并让它简单地将给定的参数转换为 jQuery ajax() 调用的参数,并设置内容类型。这样,您不必将所有这些 post() 函数重写为 ajax() 函数,而只需将它们全部从 post 更改为 xpost (或其他)。
回答by Tracker1
I know this is a late answer, I actually have a shortcut method that I use for posting/reading to/from MS based services.. it works with MVC as well as ASMX etc...
我知道这是一个迟到的答案,我实际上有一个快捷方法,用于发布/读取基于 MS 的服务..它适用于 MVC 以及 ASMX 等...
Use:
用:
$.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));
NOTE: I also have a JSON.parseAjax method that is modified from json.org's JS file, that adds handling for the MS "/Date(...)/" dates...
注意:我还有一个 JSON.parseAjax 方法,它是从 json.org 的 JS 文件修改而来的,它增加了对 MS "/Date(...)/" 日期的处理...
The modified json2.js file isn't included, it uses the script based parser in the case of IE8, as there are instances where the native parser breaks when you extend the prototype of array and/or object, etc.
不包括修改后的 json2.js 文件,它在 IE8 的情况下使用基于脚本的解析器,因为在扩展数组和/或对象等原型时,本地解析器会中断。
I've been considering revamping this code to implement the promises interfaces, but it's worked really well for me.
我一直在考虑修改这段代码来实现 promises 接口,但它对我来说非常有效。
回答by Ruwen
This simple jquery API extention (from: https://benjamin-schweizer.de/jquerypostjson.html) for $.postJSON() does the trick. You can use postJSON() like every other native jquery Ajax call. You can attach event handlers and so on.
这个用于 $.postJSON() 的简单 jquery API 扩展(来自:https: //benjamin-schweizer.de/jquerypostjson.html)可以解决问题。您可以像使用其他原生 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
});
};
Like other Ajax APIs (like $http from AngularJS) it sets the correct contentType to application/json. You can pass your json data (javascript objects) directly, since it gets stringified here. The expected returned dataType is set to JSON. You can attach jquery's default event handlers for promises, for example:
与其他 Ajax API(如来自 AngularJS 的 $http)一样,它将正确的 contentType 设置为 application/json。您可以直接传递 json 数据(javascript 对象),因为它在此处被字符串化。预期返回的数据类型设置为 JSON。您可以为 Promise 附加 jquery 的默认事件处理程序,例如:
$.postJSON(apiURL, jsonData)
.fail(function(res) {
console.error(res.responseText);
})
.always(function() {
console.log("FINISHED ajax post, hide the loading throbber");
});
回答by dbrin
At the heart of the matter is the fact that JQuery at the time of writing does not have a postJSON method while getJSON exists and does the right thing.
问题的核心是在撰写本文时 JQuery 没有 postJSON 方法,而 getJSON 存在并且做正确的事情。
a postJSON method would do the following:
postJSON 方法将执行以下操作:
postJSON = function(url,data){
return $.ajax({url:url,data:JSON.stringify(data),type:'POST', contentType:'application/json'});
};
and can be used like this:
并且可以这样使用:
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
});
回答by Ben Creasy
The documentationcurrently shows that as of 3.0, $.post will accept the settings object, meaning that you can use the $.ajax options. 3.0 is not released yet and on the committhey're talking about hiding the reference to it in the docs, but look for it in the future!
该文件目前显示,截至3.0,$。员额将接受设置对象,这意味着你可以使用$阿贾克斯选项。3.0 还没有发布,在提交时他们正在谈论在文档中隐藏对它的引用,但在未来寻找它!