Неможливо встановити тип вмісту на "application / json" в jQuery.ajax


106

Коли у мене є цей код

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

Це не допомогло, у мене метод не допускає помилки з сервера.

Ось що говорить мій скрипаль

введіть тут опис зображення

Отже, тепер я можу бути впевнений, що мій сервер приймає POST, GET, OPTIONS (якщо заголовки відповідей працюють так, як я очікую). Але чому "Метод не дозволений"?

У WebView відповідь від сервера (ви можете бачити Raw response на малюнку вище) виглядає приблизно так

введіть тут опис зображення


2
ви повинні спробувати метод
JSON.stringfy

Послухайте. Це для мене дуже добре працює: stackoverflow.com/questions/9754767/…
Fanda,

У мене виникає точно така ж проблема, але я працюю з NodeJS як бекенд, а також я встановлюю всі запити OPTION не тільки для того, щоб бути прийнятими, але щоб змусити відповідь у 200 на всі запити OPTION, щоб решта петицій працювала, як очікувалося без відповіді ...
HeberLZ

1
Привіт @ Віталій Корсаков. Ви вирішили свою проблему? Я зустрічаюся з тією ж проблемою, тобто не можу змінити contentType.
worldterminator

1
У мене була така ж проблема , і тільки що він працює .. рішення у відповідь на цій сторінці: stackoverflow.com/questions/20295080 / ... ..разработать Підводячи підсумок: «При використанні CONTENTTYPE:" додатки / JSON "ви не в змозі розраховувати на заповнення $ _POST. $ _POST заповнюється лише для типів вмісту, кодованого формою. Як такий, вам потрібно прочитати ваші дані з вихідного входу PHP ".. Я бачу, зараз ви не використовуєте php на сервері З іншого боку, але, сподіваємось, ця інформація в чомусь допомагає
Сара

Відповіді:


91

Здається, що видалення 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. Здавалося б, тип вмісту, що кодується формою, зашифрований у формі за замовчуванням, вважається безпечним і тому не проходить додаткових крос-доменних перевірок.

Схоже, вам потрібно буде додати згадані раніше заголовки до відповіді ваших серверів на запит 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);
  }
});​

Список літератури:


Я хочу втратити зв'язок між клієнтом і сервером. Сервер - це RESTful сервіс, і всі клієнти цього сервісу повинні знати його URL.
Віталій Корсаков

Чи можете ви надати ще кілька деталей у своєму дописі про сценарій цього питання? Якщо ваші клієнти будуть знаходитись у різних доменах, у вас можуть виникнути проблеми з походженням.
Майк Вейд

Я розмістив додаткову інформацію про сторону сервера. Зараз сервер і клієнт як у localhost, але в портах відрізняються. Пізніше вони, швидше за все, будуть в різних областях.
Віталій Корсаков

Здається, що проблема, з якою ви стикаєтеся, пов’язана з тією ж політикою щодо походження, можливо, варто поглянути на jsonp і питання, на яке я пов’язаний у своїй відповіді на додаток до цих питань, пов’язаних із посиланнями . jquery cross cross guide - Я не маю великого досвіду роботи з запитами між домену, але, сподіваємось, ці посилання вам будуть корисні.
Майк Вейд

Я не думаю, що це проблема, тому що все працює нормально, коли я не передаю жодні параметри, а тип вмісту - це application / x-www-form-urlencoded. Але мені не потрібен запит POST, якщо я не зміг пропустити жодних параметрів.
Віталій Корсаков

41

Я можу показати вам, як я ним користувався

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

Те саме, що в наступній відповіді. Я не можу не вказати URL на сервері, де розміщені всі сервісні функції
Віталій Корсаков

@VitaliiKorsakov я пішов, ти розібрався зі своєю проблемою.
Амрітпал Сінгх

Дякую за відповідь! Я не можу повірити, що це не прописано деінде. Звичайно, схоже, що JQuery опублікує json, коли
вказаний

1
@JasonGoemaat Параметр dataType в jQuery використовується лише для розбору повернутого тіла відповіді. Якщо ви прочитаєте документацію, то побачите, що вона навіть не потрібна. Значення за замовчуванням для dataType - інтелектуальна здогадка. Ваша проблема полягає в тому, що атрибут даних у jquery не може бути налаштований. Ви не можете сказати, як jquery повинен аналізувати об'єкт даних. Ось чому ви повинні серіалізувати json раніше. Тому що jquery серіалізується лише для url-form-encode
Loïc Faure-Lacroix

12

Тому все, що потрібно зробити для цього, це додати:

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

як поле до вашого запиту на пошту, і воно працюватиме.


api.jquery.com/jquery.ajax Якщо ви подивитесь у документацію, вона говорить, що без вказівки вона за замовчуванням до 'application / x-www-form-urlencoded; charset = UTF-8 '(саме тому це і відбувається. Idk, чому просто встановити contentType не працює. Ви можете перевірити, яку версію jQuery у вас є, і оновити, якщо ви використовуєте стару версію).
Коді Жак

Це не працює. Незважаючи на те, що я маю type: "POST", він надсилає OPTIONS.
user9645

5

Я розпізнав ці екрани, використовую CodeFluentEntities, і у мене є рішення, яке працювало і для мене.

Я використовую цю конструкцію:

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

як ви бачите, якщо я використовую

contentType: "",

або

contentType: "text/plain", //chrome

Все працює добре.

Я не на 100% впевнений, що це все, що потрібно, тому що я також змінив заголовки.


5

Якщо ви користуєтесь цим:

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
на жаль правильна відповідь для мене. Опустіть contentType і просто використовуйте dataType, щоб обійти сміття CORS OPTIONS, яке багато сервісів просто не реалізують належним чином. Так дратує.
Umopepisdn

2

Я знайшов рішення цієї проблеми тут . Не забудьте дозволити дієслово ОПЦІЇ на обробці служби IIS.

Добре працює. Дякую Андре Педросо. :-)


1

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

Firefox здійснює попередній дзвінок на ваш сервер / URL відпочинку, щоб перевірити, які варіанти дозволені. Це запит "ВАРІАНТИ", на який ваш сервер не відповідає відповідним чином. Якщо на цей виклик OPTIONS відповідено правильним, виконується другий виклик, який є фактичним запитом "POST" із вмістом json.

Це відбувається лише під час здійснення міждоменного дзвінка. У вашому випадку виклик " http://localhost:16329/Hello" замість того, щоб викликати шлях URL під тим самим доменом "/ Привіт"

Якщо ви маєте намір здійснити міждоменний дзвінок, вам потрібно буде покращити свій клас спокою за допомогою анотованого методу, він підтримує 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

Я отримав рішення надсилати дані 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. Сподіваємось, це допоможе комусь.


3
Він насправді не перетворюється на OPTION, він надсилає запит на передполіт CORS, щоб перевірити, чи дозволено POST. Якщо це не повертається правильно, POST не відбувається.
Umopepisdn

0

Привіт Ці два рядки працювали для мене.

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

Спасибі, Прашант

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.