Невозможно установить контент-тип в 'application/json' в jQuery.ajax

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

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

Почему? Что такое ОПЦИИ, когда он должен быть там? И где мой контент-тип установлен в 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 response на рисунке выше) выглядит так:

enter image description here

Ответ 1

Казалось бы, удаление 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 отправки "ОПЦИИ" как REQUEST_METHOD в Firefox

Edit: После нескольких исследований я узнал, что заголовок 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);
  }
});​

Литература:

Ответ 2

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

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

Ответ 3

Итак, все, что вам нужно сделать для этого, - добавить:

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

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

Ответ 4

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

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

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

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

contentType: "",

или

contentType: "text/plain", //chrome

Все работает нормально.

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

Ответ 5

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

Прекрасно работает. Спасибо, Андре Педрозу.: -)

Ответ 6

У меня была такая же проблема. Я запускаю приложение java rest на сервере jboss. Но я думаю, что решение похоже на веб-приложение ASP.NET.

Firefox делает предварительный вызов на ваш сервер/источник URL, чтобы проверить, какие параметры разрешены. Это запрос "ОПЦИИ", который ваш сервер не отвечает соответственно. Если этот ответ 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")

Ответ 7

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

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