Невозможно установить тип контента в 'application / json' в jQuery.ajax - PullRequest
93 голосов
/ 18 марта 2012

Когда у меня есть этот код

$.ajax({
    type: 'POST',
    //contentType: "application/json",
    url: 'http://localhost:16329/Hello',
    data: { name: 'norm' },
    dataType: 'json'
});

в Fiddler, я вижу следующий необработанный запрос

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

Это не помогло, у меня Метод не разрешен Ошибка с сервера.

Вот что говорит мой скрипач

enter image description here

Итак, теперь я могу быть уверен, что мой сервер принимает POST, GET, OPTIONS (если заголовки ответа работаюткак я и ожидал).Но почему «Метод не разрешен»?

В ответе WebView от сервера (вы можете увидеть Raw ответ на картинке выше) выглядит так:

enter image description here

Ответы [ 8 ]

81 голосов
/ 18 марта 2012

Может показаться, что удаление 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);
  }
});​

Ссылки:

34 голосов
/ 18 марта 2012

Я могу показать вам, как я это использовал

  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;
                }
            }
        });
    }
9 голосов
/ 19 января 2016

Так что все, что вам нужно сделать, чтобы это работало, это добавить:

headers: {
    'Accept': 'application/json',
    'Content-Type': 'application/json'
}

как поле для вашего почтового запроса, и оно будет работать.

4 голосов
/ 27 февраля 2015

Я распознал эти экраны, я использую CodeFluentEntities, и у меня есть решение, которое также работает для меня.

Я использую эту конструкцию:

$.ajax({
   url: path,
   type: "POST",
   contentType: "text/plain",
   data: {"some":"some"}
}

как видите, если я использую

contentType: "",

или

contentType: "text/plain", //chrome

Все отлично работает.

Я не уверен на 100%, что это все, что вам нужно, потому что я также сменил заголовки.

2 голосов
/ 11 сентября 2013

Я нашел решение этой проблемы здесь .Не забудьте разрешить глаголы OPTIONS в обработчике службы приложений IIS.

Работает нормально.Спасибо Андре Педросо.: -)

1 голос
/ 04 марта 2017

Если вы используете это:

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) { }
  }
)
1 голос
/ 09 декабря 2014

У меня была такая же проблема. Я запускаю приложение отдыха 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")
0 голосов
/ 28 марта 2018

Я получил решение отправить данные 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. Надеюсь, это кому-нибудь поможет.

...