Невозможно выполнить HTTP-вызов PUT / POST / DELETE с использованием CORS в JQuery 1.6.4. - PullRequest
14 голосов
/ 28 сентября 2011

Итак, я могу успешно сделать GET-вызов в мой сервис, используя CORS. Однако что-то должно идти не так на уровне предпечатной проверки для операций POST, PUT и DELETE. Однако, насколько я могу судить, ответы заголовков, которые мой сервер возвращает в ответ на запрос OPTIONS, являются правильными и соответствуют тем, которые описаны в

Вот мой код JavaScript, использующий $ .ajax в JQuery 1.6.4.

$.ajax({
  url: 'http://myhome:8080/TaskApproval/resources/tasks/2',
  context: this,
  data: '<?xml version="1.0" encoding="UTF-8"?> <task> <description>Get carrots from the grocery store</description><originator>Chris</originator><subject>Get Carrots !!</subject><taskId>2</taskId> </task> ',
  timeout: 30000,
  type: 'PUT',
  contentType: 'application/xml',
  success: function(response) {
    alert(response);
    result = response;
  },
  error: function(xhr) {
    alert('Error!  Status = ' + xhr.status + " Message = " + xhr.statusText);
  }
});

Теперь, так выглядит мой HTTP Trail, любезно предоставленный Firebug.

Запрос:

OPTIONS /TaskApproval/resources/tasks/2 HTTP/1.1
Host: widgethome:8080
User-Agent: Mozilla/5.0 (Windows NT 5.1; rv:6.0.2) Gecko/20100101 Firefox/6.0.2
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: en-us,en;q=0.5
Accept-Encoding: gzip, deflate
Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.7
Connection: keep-alive
Origin: http://localhost:8080
Access-Control-Request-Method: PUT
Access-Control-Request-Headers: content-type

Ответ:

HTTP/1.1 200 OK
X-Powered-By: Servlet/3.0
Server: GlassFish v3
Allow: OPTIONS,GET,DELETE,HEAD,PUT, POST
Access-Control-Allow-Origin: *
Access-Control-Allow-Methods: POST, GET, OPTIONS, PUT, DELETE
Access-Control-Max-Age: 1000
Access-Control-Allow-Headers: *
Content-Type: application/xml
Content-Length: 2792
Date: Wed, 28 Sep 2011 18:21:11 GMT

Тогда нет никакого PUT (или POST или DELETE), я просто получаю этот раздражающий бесполезный объект xhr, который выглядит так:

readyState  0 
responseText    ""
status  0
statusText  "error"

Я очень озадачен тем, что если я затем удаляю contentType в своем вызове Ajax, и он отправляет недопустимый тип контента для моего приложения, браузер фактически отправляет мой запрос PUT, который не выполняется, поскольку Content-Type не является application / XML. Смотрите ниже:

$.ajax({
  url: 'http://myhome:8080/TaskApproval/resources/tasks/2',
  data: '<?xml version="1.0" encoding="UTF-8"?> <task> <description>Get carrots from the grocery store</description><originator>Chris</originator><subject>Get Carrots !!</subject><taskId>2</taskId> </task> ',
  timeout: 30000,
  type: 'PUT',
  //contentType: 'application/xml',
  success: function(response) {
    alert(response);
    result = response;
  },
  error: function(xhr) {
    alert('Error!  Status = ' + xhr.status + " Message = " + xhr.statusText);
  }
});

Приводит к этому HTTP-следу, опять же любезно предоставлено Firebug:

Запрос параметров:

OPTIONS /TaskApproval/resources/tasks/2 HTTP/1.1
Host: myhome:8080
User-Agent: Mozilla/5.0 (Windows NT 5.1; rv:6.0.2) Gecko/20100101 Firefox/6.0.2
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: en-us,en;q=0.5
Accept-Encoding: gzip, deflate
Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.7
Connection: keep-alive
Origin: http://localhost:8080
Access-Control-Request-Method: PUT

Варианты ответа:

HTTP/1.1 200 OK
X-Powered-By: Servlet/3.0
Server: GlassFish v3
Allow: OPTIONS,GET,DELETE,HEAD,PUT, POST
Access-Control-Allow-Origin: *
Access-Control-Allow-Methods: POST, GET, OPTIONS, PUT, DELETE
Access-Control-Max-Age: 1000
Access-Control-Allow-Headers: *
Content-Type: application/xml
Content-Length: 2792
Date: Wed, 28 Sep 2011 18:26:23 GMT

Запрос на размещение:

PUT /TaskApproval/resources/tasks/2 HTTP/1.1
Host: myhome:8080
User-Agent: Mozilla/5.0 (Windows NT 5.1; rv:6.0.2) Gecko/20100101 Firefox/6.0.2
Accept: */*
Accept-Language: en-us,en;q=0.5
Accept-Encoding: gzip, deflate
Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.7
Connection: keep-alive
Content-Type: application/x-www-form-urlencoded; charset=UTF-8
Referer: http://localhost:8080/TaskApproval/crossdomain.html
Content-Length: 197
Origin: http://localhost:8080

Ответ на вопрос:

HTTP/1.1 415 Unsupported Media Type
X-Powered-By: Servlet/3.0
Server: GlassFish v3
Content-Type: text/html
Content-Length: 1069
Date: Wed, 28 Sep 2011 18:26:23 GMT

415 имеет смысл, потому что я не поддерживаю контент application / x-www-form-urlencoded, только application / xml. Чего я не понимаю, так это почему установка Content-Type правильно предотвращает PUT?

Спасибо за понимание! Я искал в интернете довольно долгое время и не могу найти решение этой проблемы.

Ответы [ 2 ]

32 голосов
/ 29 сентября 2011

Вы должны включить заголовки CORS как в предпечатную, так и в фактическую реакцию. Поэтому попробуйте включить следующие заголовки в ответ PUT вашего сервера:

Access-Control-Allow-Origin: *
Access-Control-Allow-Methods: POST, GET, OPTIONS, PUT, DELETE
Access-Control-Allow-Headers: Content-Type

Еще одна вещь, на которую следует обратить внимание, это то, что в спецификации CORS '*' не указано допустимое значение для Access-Control-Allow-Headers:

http://www.w3.org/TR/cors/#access-control-allow-headers-response-he

Вместо этого вы должны попытаться явно перечислить все заголовки запроса следующим образом:

Access-Control-Allow-Headers: Content-Type

Вы должны включить Content-Type, потому что Content-Type не считается простым заголовком, если его значение не является application / x-www-form-urlencoded, multipart / form-data или text / plain (см. Спецификацию CORS). подробнее о простых заголовках).

0 голосов
/ 21 января 2017

Не забудьте убедиться, что на ваш запрос опциона перед боем также ответили:

Access-Control-Allow-Origin: *
Access-Control-Allow-Methods: POST, GET, OPTIONS, PUT, DELETE
Access-Control-Allow-Headers: Content-Type
...