Невозможно установить тип контента в 'application/json' в jQuery.ajax
Когда у меня есть этот код
$.ajax({
type: 'POST',
//contentType: "application/json",
url: 'http://localhost:16329/Hello',
data: { name: 'norm' },
dataType: 'json'
});
в фиддлере вижу следующий сырой запрос
POST http://localhost:16329/Hello HTTP/1.1
Host: localhost:16329
User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64; rv:10.0.2) Gecko/20100101 Firefox/10.0.2
Accept: application/json, text/javascript, */*; q=0.01
Accept-Language: ru-ru,ru;q=0.8,en-us;q=0.5,en;q=0.3
Accept-Encoding: gzip, deflate
Connection: keep-alive
Content-Type: application/x-www-form-urlencoded; charset=UTF-8
Referer: http://localhost:14693/WebSite1/index.html
Content-Length: 9
Origin: http://localhost:14693
Pragma: no-cache
Cache-Control: no-cache
name=norm
Но я пытаюсь установить тип контента из application/x-www-form-urlencoded в application / json. Но этот код
$.ajax({
type: "POST",
contentType: "application/json",
url: 'http://localhost:16329/Hello',
data: { name: 'norm' },
dataType: "json"
});
Создает странный запрос (который я вижу в Fiddler)
OPTIONS http://localhost:16329/Hello HTTP/1.1
Host: localhost:16329
User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64; rv:10.0.2) Gecko/20100101 Firefox/10.0.2
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: ru-ru,ru;q=0.8,en-us;q=0.5,en;q=0.3
Accept-Encoding: gzip, deflate
Connection: keep-alive
Origin: http://localhost:14693
Access-Control-Request-Method: POST
Access-Control-Request-Headers: content-type
Pragma: no-cache
Cache-Control: no-cache
Это почему? Что такое ОПЦИИ, когда там должен быть POST? И где мой тип контента установлен на application/json? И параметры запроса пошли по какой-то причине.
ОБНОВЛЕНИЕ 1
На стороне сервера у меня действительно простой RESTful сервис.
[AspNetCompatibilityRequirements(RequirementsMode = AspNetCompatibilityRequirementsMode.Allowed)]
public class RestfulService : IRestfulService
{
[WebInvoke(
Method = "POST",
UriTemplate = "Hello",
ResponseFormat = WebMessageFormat.Json)]
public string HelloWorld(string name)
{
return "hello, " + name;
}
}
Но по какой-то причине я не могу вызвать этот метод с параметрами.
ОБНОВЛЕНИЕ 2
Извините, что не отвечал так долго.
Я добавил эти заголовки в ответ моего сервера
Access-Control-Allow-Origin: *
Access-Control-Allow-Headers: Content-Type
Access-Control-Allow-Methods: POST, GET, OPTIONS
Это не помогло, у меня есть метод не допускается ошибка с сервера.
Вот что говорит мой скрипач
Итак, теперь я могу быть уверен, что мой сервер принимает POST, GET, OPTIONS (если заголовки ответа работают так, как я ожидал). Но почему "Метод не разрешен"?
В WebView ответ от сервера (вы можете увидеть необработанный ответ на картинке выше) выглядит следующим образом
11 ответов
Казалось бы, удаление http://
из параметра url обеспечивает отправку правильного заголовка HTTP POST.
Я не думаю, что вам нужно полностью определить имя хоста, просто используйте относительный URL, как показано ниже.
$.ajax({
type: "POST",
contentType: "application/json",
url: '/Hello',
data: { name: 'norm' },
dataType: "json"
});
Пример моего, который работает:
$.ajax({
type: "POST",
url: siteRoot + "api/SpaceGame/AddPlayer",
async: false,
data: JSON.stringify({ Name: playersShip.name, Credits: playersShip.credits }),
contentType: "application/json",
complete: function (data) {
console.log(data);
wait = false;
}
});
Возможно связанные: jQuery $.ajax (), $.post отправляет "OPTIONS" как REQUEST_METHOD в Firefox
Изменить: После еще одного исследования я обнаружил, что заголовок OPTIONS используется, чтобы выяснить, разрешен ли запрос из исходного домена. Используя fiddler, я добавил следующее в заголовки ответа с моего сервера.
Access-Control-Allow-Origin: *
Access-Control-Allow-Headers: Content-Type
Access-Control-Allow-Methods: POST, GET, OPTIONS
Когда браузер получил этот ответ, он отправил правильный запрос POST с данными json. Казалось бы, тип контента по умолчанию в форме urlencoded считается безопасным и поэтому не подвергается дополнительным междоменным проверкам.
Похоже, вам нужно будет добавить ранее упомянутые заголовки в ответ сервера на запрос OPTIONS. Конечно, вы должны настроить их так, чтобы они разрешали запросы от определенных доменов, а не от всех.
Я использовал следующий jQuery, чтобы проверить это.
$.ajax({
type: "POST",
url: "http://myDomain.com/path/AddPlayer",
data: JSON.stringify({
Name: "Test",
Credits: 0
}),
//contentType: "application/json",
dataType: 'json',
complete: function(data) {
$("content").html(data);
}
});
Рекомендации:
Я могу показать вам, как я это использовал
function GetDenierValue() {
var denierid = $("#productDenierid").val() == '' ? 0 : $("#productDenierid").val();
var param = { 'productDenierid': denierid };
$.ajax({
url: "/Admin/ProductComposition/GetDenierValue",
dataType: "json",
contentType: "application/json;charset=utf-8",
type: "POST",
data: JSON.stringify(param),
success: function (msg) {
if (msg != null) {
return msg.URL;
}
}
});
}
Так что все, что вам нужно сделать, чтобы это работало, это добавить:
headers: {
'Accept': 'application/json',
'Content-Type': 'application/json'
}
как поле для вашего почтового запроса, и он будет работать.
Если вы используете это:
contentType: "application/json"
AJAX не будет отправлять параметры GET или POST на сервер.... не знаю почему.
Мне потребовались часы, чтобы выучить это сегодня.
Просто используйте:
$.ajax(
{ url : 'http://blabla.com/wsGetReport.php',
data : myFormData, type : 'POST', dataType : 'json',
// contentType: "application/json",
success : function(wsQuery) { }
}
)
Я узнал эти экраны, я использую CodeFluentEntities, и у меня есть решение, которое также работает для меня.
Я использую эту конструкцию:
$.ajax({
url: path,
type: "POST",
contentType: "text/plain",
data: {"some":"some"}
}
как видите, если я использую
contentType: "",
или же
contentType: "text/plain", //chrome
Все отлично работает
Я не уверен на 100%, что это все, что вам нужно, потому что я также сменил заголовки.
Я боролся с этой же проблемой, и это было вызвано отсутствием JSON.stringfy(), т.е.
data: JSON.stringfy({ name: 'norm' }),
Надеюсь, это сэкономит кому-то еще много времени!
Я нашел решение этой проблемы здесь. Не забудьте разрешить опцию глагола в обработчике службы приложения IIS.
Работает отлично. Спасибо Андре Педросо.:-)
Я была такая же проблема. Я запускаю приложение отдыха Java на сервере Jboss. Но я думаю, что решение похоже на веб-приложение ASP .NET.
Firefox предварительно обращается к вашему серверу / URL-адресу rest, чтобы проверить, какие опции разрешены. Это запрос "OPTIONS", на который ваш сервер не отвечает соответственно. Если на этот вызов OPTIONS получен правильный ответ, выполняется второй вызов, который является фактическим запросом POST с содержимым json.
Это происходит только при выполнении междоменного вызова. В вашем случае зоветhttp://localhost:16329/Hello
'вместо вызова пути URL в том же домене'/Hello'
Если вы намереваетесь совершать междоменный вызов, вам нужно улучшить класс обслуживания отдыха с помощью аннотированного метода, который поддерживает http-запрос "OPTIONS". Это соответствующая реализация Java:
@Path("/rest")
public class RestfulService {
@POST
@Path("/Hello")
@Consumes(MediaType.APPLICATION_JSON)
@Produces(MediaType.TEXT_PLAIN)
public string HelloWorld(string name)
{
return "hello, " + name;
}
//THIS NEEDS TO BE ADDED ADDITIONALLY IF MAKING CROSS-DOMAIN CALLS
@OPTIONS
@Path("/Hello")
@Produces(MediaType.TEXT_PLAIN+ ";charset=utf-8")
public Response checkOptions(){
return Response.status(200)
.header("Access-Control-Allow-Origin", "*")
.header("Access-Control-Allow-Headers", "Content-Type")
.header("Access-Control-Allow-Methods", "POST, OPTIONS") //CAN BE ENHANCED WITH OTHER HTTP CALL METHODS
.build();
}
}
Так что я думаю, что в.NET вы должны добавить дополнительный метод с пометкой
[WebInvoke(
Method = "OPTIONS",
UriTemplate = "Hello",
ResponseFormat = WebMessageFormat.)]
где установлены следующие заголовки
.header("Access-Control-Allow-Origin", "*")
.header("Access-Control-Allow-Headers", "Content-Type")
.header("Access-Control-Allow-Methods", "POST, OPTIONS")
Привет, эти две строчки у меня сработали.
contentType: "application / json; charset=utf-8", dataType:"json"
$.ajax({
type: "POST",
url: "/v1/candidates",
data: obj,
**contentType:"application/json; charset=utf-8",
dataType:"json",**
success: function (data) {
table.row.add([
data.name, data.title
]).draw(false);
}
Спасибо, Прашант
Я получил решение отправить данные JSON с помощью запроса POST через jquery ajax. Я использовал ниже код
var data = new Object();
data.p_clientId = 4;
data = JSON.stringify(data);
$.ajax({
method: "POST",
url: "http://192.168.1.141:8090/api/Client_Add",
data: data,
headers: {
'Accept': 'application/json',
'Content-Type': 'text/plain'
}
})
.done(function( msg ) {
alert( "Data Saved: " + msg );
});
});
});
я использовал 'Content-Type': 'text/plain'
в заголовке, чтобы отправить необработанные данные JSON.
Потому что, если мы используем Content-Type: 'application/json'
методы запроса, преобразованные в OPTION, но использующие Content-Type: 'test/plain'
метод не конвертируется и остается как POST. Надеюсь, это поможет кому-то.
В документации jQuery.ajax contentType указывает тип контента для отправки на сервер. Значение по умолчанию"application/x-www-form-urlencoded; charset=UTF-8"
. Для междоменных запросов, если тип контента отличается от ,multipart/form-data
, илиtext/plain
установлен, метод будет отправлен в заголовке запроса. Это проверка, которую ajax выполняет с помощью политик CORS, чтобы проверить, разрешены ли методы, которые вы запрашиваете на сервере (в данном случае POST) в вашем домене. Если метод на вашем сервере, на котором размещен API, разрешен, запрос вы сделали на сервер изначально сделано, в этом случае POST отправляется.
Если вы делаете запрос к тому же домену и тому же порту, метод не отправляется. В этом случае одним из решений является использование"http://localhost:<port>..."
или просто используйте относительные пути, где вы собираетесь сделать запрос.
Но если REST API в вашем бэкенде находится в другом домене, то есть два решения.
- Не ставьте ajax, а отправьте данные либо в формате JSON в виде объекта, либо в виде строки, либо строки с параметрами для отправки типа .
- Включите CORS в своем Rest API (то есть разрешите OPTIONS, методы POST для любого домена или вашего домена, в котором вы делаете запрос).
Проблема в том, что в некоторых случаях необходимо установить тип контента для отправки как , потому что сервер, на котором размещен API, не принимает другие типы контента.
Если у вас есть контроль над BackEnd и REST API, я рекомендую включить на нем CORS. (Также применяется, если это тот же домен, но другой порт).
Access-Control-Allow-Origin: *
Access-Control-Allow-Headers: Content-Type
Access-Control-Allow-Methods: POST, GET, OPTIONS
Или также разрешите другие типы контента, такие какapplication/x-www-form-urlencoded
или закодировать его таким образом, чтобы он также принимал строки сkey=value
параметры. Это предотвращает отправку jQueryOPTIONS
в его заголовке запроса.
И последнее: если используется и сервер ожидает"application/json"
также, вы должны использовать наdata
, так как при отправке запроса на сервер он вроде бы принимает JSON как строку, а не как объект. В моем случае не используетсяJSON.stringify()
и используяcontentType: "application/json"
, вернул мне ошибку сервера со статусом 500