2012-03-17 3 views
78

Когда у меня есть этот кодНевозможно установить тип содержимого для «приложения/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 to 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? И параметры запроса по какой-то причине пошли.

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

Но по какой-то причине я не могу назвать этот метод параметрами.

UPDATE 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

+1

вы должны попробовать JSON.stringfy() метод –

+0

NOP, не помогло –

+0

посмотреть здесь. Это работает для меня очень хорошо: http://stackoverflow.com/questions/9754767/cannot-set-content-type-to-application-json-in-jquery-ajax/18740041#18740041 – Fanda

ответ

24

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

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

То же самое, что и в следующем ответе. Я не могу не указывать URL-адрес сервера, на котором размещены все сервисные функции. –

+0

@VitaliiKorsakov я ушел, вы разобрались в своей проблеме. –

+0

нет, см. Мой первый пост для дополнительной информации –

65

Было бы кажется, что удаление 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 sending "OPTIONS" as REQUEST_METHOD in 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); 
    } 
});​ 

Ссылки:

+0

Я хочу потерять связь между клиентом и сервером. Сервер - это служба RESTful, и все клиенты этой службы должны знать URL-адрес. –

+0

Можете ли вы предоставить более подробную информацию в своем посте о сценарии этого вопроса? Если ваши клиенты будут находиться в разных доменах, вы можете столкнуться с такими же проблемами происхождения. – Spike

+0

Я разместил дополнительную информацию о стороне сервера. Прямо сейчас сервер и клиент как на localhost, так и на разных портах. Позже они, скорее всего, будут в разных доменах. –

2

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

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

1

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

Firefox делает предварительный вызов на ваш сервер/источник URL, чтобы проверить, какие параметры разрешены. Это запрос «ОПЦИИ», который ваш сервер не отвечает соответственно. Если этот ответ OPTIONS отвечает правильно, выполняется второй вызов, который является фактическим запросом «POST» с содержимым json.

Это происходит только при выполнении междоменного вызова. В вашем случае вызов «http://localhost:16329/Hello» вместо вызова пути URL-адреса в том же домене «/ Hello»

Если вы намерены совершить междоменный вызов, вам необходимо повысить класс обслуживания отдыха с помощью аннотированного метода, ОПЦИИ "http-запрос. Это соответствует внедрению java:

Так что я предполагаю, что.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") 
4

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

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

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

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

contentType: "", 

или

contentType: "text/plain", //chrome 

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

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

8

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

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

как поле на запрос пост, и он будет работать.

+0

http://api.jquery.com/jquery.ajax/ Если вы посмотрите в документации, то говорится, что без указания его по умолчанию установлено значение 'application/x-www-form-urlencoded; charset = UTF-8 '(вот почему это происходит. Idk, почему просто настройка contentType не работает. Возможно, вам захочется проверить, какая версия jQuery у вас есть, и обновить, если вы находитесь на старой версии). –

+0

Это не работает. Даже если у меня есть тип: «POST», он отправляет «ОПЦИИ». – user9645

0

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

contentType: "application/json" 

AJAX не будет отправлено GET или POST PARAMS на сервер .... не знаю почему.

Мне потребовались часы, чтобы ослабить его сегодня.

Просто используйте:

$.ajax(
    { url : 'http://blabla.com/wsGetReport.php', 
    data : myFormData, type : 'POST', dataType : 'json', 
    // contentType: "application/json", 
    success : function(wsQuery) { } 
    } 
)