JQuery - Как сделать $.post() использовать contentType = application/json?
Я заметил, что при использовании $.post() в jquery значение contentType по умолчанию - application/x-www-form-urlencoded - когда мой код mvc asp.net должен иметь contentType = application/json
(см. этот вопрос, почему я должен использовать application/json: ASPNET MVC - Почему ModelState.IsValid false " Поле x требуется", когда это поле имеет значение?)
Как я могу сделать $.post() отправить contentType = application/json? У меня уже есть большое количество функций $.post(), поэтому я не хочу менять значение $.ajax(), потому что это займет слишком много времени
Если я попробую
$.post(url, data, function(), "json")
У него все еще есть contentType = application/x-www-form-urlencoded. Так что же делает параметр "json", если он не меняет contenttype на json?
Если я попробую
$.ajaxSetup({
contentType: "application/json; charset=utf-8"
});
Это работает, но влияет на все $.get и $.post, которые у меня есть, и вызывает некоторые нарушения.
Итак, есть ли способ изменить поведение $.post() для отправки contentType = application/json?
Ответы
Ответ 1
Я думаю, вам, возможно, придется
1. Измените источник, чтобы $.post всегда использовал тип данных JSON, поскольку он действительно является ярлыком для предварительно настроенного вызова $.ajax
Или
2. Определите свою собственную функцию утилиты, которая является ярлыком для конфигурации $.ajax
, которую вы хотите использовать
или
3. Вы можете перезаписать $.post function
своей собственной реализацией через патч обезьяны.
Тип данных JSON в вашем примере относится к типу данных, возвращаемому с сервера, а не к формату, отправленному на сервер.
Ответ 2
$.ajax({
url:url,
type:"POST",
data:data,
contentType:"application/json; charset=utf-8",
dataType:"json",
success: function(){
...
}
})
Смотрите: jQuery.ajax()
Ответ 3
Наконец, я нашел решение, которое работает для меня:
jQuery.ajax ({
url: myurl,
type: "POST",
data: JSON.stringify({data:"test"}),
dataType: "json",
contentType: "application/json; charset=utf-8",
success: function(){
//
}
});
Ответ 4
В итоге я добавил следующий jQuery в мой 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
});
};
И использовать его
$.postJSON('http://url', {data: 'goes', here: 'yey'}, function (data, status, xhr) {
alert('Nailed it!')
});
Это было сделано путем простого копирования кода "get" и "post" из исходных источников JQuery и жесткого кодирования нескольких параметров, чтобы заставить JSON POST.
Спасибо!
Ответ 5
используйте только
jQuery.ajax ({
url: myurl,
type: "POST",
data: mydata,
dataType: "json",
contentType: "application/json; charset=utf-8",
success: function(){
//
}
});
ОБНОВЛЕНО @JK: если вы пишете в своем вопросе только один пример кода с $.post, вы найдете в ответе соответствующий пример. Я не хочу повторять ту же информацию, которую вы уже изучили, до тех пор, пока не узнаете: $.post и $.get - это короткие формы $.ajax. Поэтому просто используйте $.ajax, и вы можете использовать полный набор параметров без изменения глобальных настроек.
Кстати, я бы не рекомендовал перезаписывать стандартный $.post. Это мое личное мнение, но для меня важно не только то, что программа работает, но и то, что все, кто читает вашу программу, понимают это одинаково. Перезапись стандартных методов без серьезной причины может следовать за непонимание при чтении кода программы. Поэтому я повторяю свою рекомендацию еще раз: просто используйте исходную форму $.ajax jQuery вместо jQuery.get
и jQuery.post
, и вы получаете программы, которые не только отлично работают, но могут быть прочитаны людьми без каких-либо недоразумений.
Ответ 6
Тип данных "json", который вы можете передать последнему параметру post(), указывает тип данных, которые функция ожидает в ответе сервера, а не тип, который он отправляет в запросе. В частности, он устанавливает заголовок "Принять".
Честно говоря, лучше всего перейти на вызов ajax(). Функция post() предназначена для удобства; упрощенная версия вызова ajax(), когда вы просто делаете простую публикацию формы. Вы не.
Если вы действительно не хотите переключаться, вы можете сделать свою собственную функцию, называемую xpost(), и просто преобразовать заданные параметры в параметры для вызова jQuery ajax() с типом содержимого задавать. Таким образом, вместо того, чтобы переписывать все функции post() в функции ajax(), вам просто нужно изменить их все из post в xpost (или что-то еще).
Ответ 7
Я знаю, что это поздний ответ. У меня на самом деле есть метод ярлыков, который я использую для публикации/чтения в/из служб на базе 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, который был изменен из JS файла json.org, который добавляет обработку для MS "/Date(...)/" дат...
Измененный файл json2.js не включен, он использует парсер, основанный на script, в случае IE8, так как есть случаи, когда собственный парсер ломается при расширении прототипа массива и/или объекта и т.д..
Я рассматривал возможность обновления этого кода для реализации интерфейсов promises, но для меня это работало очень хорошо.
Ответ 8
В основе дела лежит тот факт, что 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
});
Ответ 9
Это простое расширение API jquery (от: https://benjamin-schweizer.de/jquerypostjson.html) для $.postJSON() делает трюк. Вы можете использовать postJSON(), как и любой другой собственный вызов jquery Ajax. Вы можете присоединить обработчики событий и так далее.
$.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
});
};
Как и другие API Ajax (например, $ http от AngularJS), он устанавливает правильный тип contentType для приложения /json. Вы можете передать свои json-данные (объекты javascript) напрямую, так как здесь он становится строковым. Ожидаемый возвращаемый тип данных установлен в JSON. Вы можете присоединить обработчики событий jquery default для обещаний, например:
$.postJSON(apiURL, jsonData)
.fail(function(res) {
console.error(res.responseText);
})
.always(function() {
console.log("FINISHED ajax post, hide the loading throbber");
});
Ответ 10
Документация в настоящее время показывает, что с 3.0, $.post примет объект настроек, что означает, что вы можете использовать опции $.ajax, 3.0 еще не выпущен, и в коммите они говорят о том, чтобы скрыть ссылку на него в документах, но ищите его в будущем!
Ответ 11
У меня была аналогичная проблема со следующим кодом JavaScript:
var url = 'http://my-host-name.com/api/Rating';
var rating = {
value: 5,
maxValue: 10
};
$.post(url, JSON.stringify(rating), showSavedNotification);
Где в Fiddler я мог видеть запрос с помощью:
- Заголовок:
Content-Type: application/x-www-form-urlencoded; charset=UTF-8
- Тело:
{"value":"5","maxValue":"5"}
В результате мой сервер не смог сопоставить объект с типом серверной части.
После изменения последней строки на следующую:
$.post(url, rating, showSavedNotification);
В Fiddler я все еще мог видеть:
- Заголовок:
Content-Type: application/x-www-form-urlencoded; charset=UTF-8
- Тело:
value=5&maxValue=10
Однако сервер начал возвращать то, что я ожидал.
Ответ 12
Как насчет вашего собственного адаптера/обертки?
//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... }
});
Ответ 13
По какой-то причине установка типа содержимого в запросе ajax по предложению @Adrien не помогла мне. Тем не менее, вы действительно можете изменить тип контента, используя $.post, сделав это раньше:
$.ajaxSetup({
'beforeSend' : function(xhr) {
xhr.overrideMimeType('application/json; charset=utf-8');
},
});
Затем сделайте свой вызов $.post
:
$.post(url, data, function(), "json")
У меня были проблемы с jQuery + IIS, и это было единственное решение, которое помогло jQuery понять, как использовать кодировку windows-1252 для запросов ajax.
Ответ 14
мы можем изменить Content-type, как это в $.post
$.post(url, data, function (data, status, xhr) {xhr.setRequestHeader("Content-type", "application/x-www-form-urlencoded; charset = utf-8");});
Ответ 15
$.post не работает, если у вас есть проблема с CORS (Cross Origin Resource Sharing). Попробуйте использовать $.Ajax в следующем формате:
"$.ajax({ URL: Someurl, contentType: 'application/json', данные: requestInJSONFormat, заголовки: {'Access-Control-Allow-Origin': '*'}, dataType: 'json', тип: 'POST', асинхронный: ложный, success: function (Data) {...}
});"
Ответ 16
Вы не можете отправить application/json
напрямую - это должен быть параметр запроса GET/POST.
Так что-то вроде
$.post(url, {json: "...json..."}, function());