2008-11-18 1 views
473

При выдаче запроса HTTP DELETE URI-запрос должен полностью идентифицировать ресурс для удаления. Однако допустимо ли добавлять дополнительные метаданные как часть тела объекта запроса?Является ли тело объекта разрешено для запроса HTTP DELETE?

+2

В ASP.NET WebAPI 2 FromBody Параметры игнорируются для HttpDelete endppoints. – 2016-02-09 08:22:09

+1

У меня есть аналогичная проблема, но мой случай отличается. Я хочу выдать пакетный запрос удаления, когда хочу удалить сто объектов. Разумеется, это отличное повышение производительности для сетей до HTTP 2.0. – Singagirl 2016-09-19 20:16:02

+0

Были ли изменения в HTTP/2? – 2017-02-22 14:21:35

ответ

400

The spec не запрещает или запрещает его, поэтому я бы сказал, что это разрешено.

Microsoft видит это так же, как (я могу слышать ропот в аудитории), они утверждают, в статье MSDN о DELETE Method of ADO.NET Data Services Framework:

Если УДАЛИТЬ запрос включает в себя тело сущности, тело игнорируется [ ...]

Кроме того вот что RFC2616 (HTTP 1.1) должен сказать в отношении запросов:

  • тело объекта присутствует только тогда, когда тело сообщения присутствует (раздел 7.2)
  • наличие тела сообщения сигнализируется включением заголовка Content-Length или Transfer-Encoding (раздел 4.3)
  • тело сообщения не должно быть включено, когда спецификация методы запроса не позволяет послав сущности тела (раздел 4.3)
  • тела объекта явно запрещено в следовых reques тс только, все другие типы запросов неограниченны (раздел 9, и 9,8 специфически)

Для получения ответов, это было определено:

  • включается ли тело сообщения зависит от того, как запроса метод и статус ответа (раздел 4.3)
  • тело сообщения явно запрещено в ответах на запросы HEAD (раздел 9, и 9,4 специфически)
  • a message-body явно запрещен в 1xx (информационном), 204 (без содержимого) и 304 (не измененных) ответах (раздел 4.3)
  • все другие ответы включают тело сообщения, хотя оно может быть нулевой длины (раздел 4.3)
+7

@ Джейсон Определенно. Вы также можете использовать пользовательские заголовки для передачи дополнительных данных, но почему бы не использовать тело запроса. – Tomalak 2012-01-06 07:55:19

+50

Несмотря на то, что спецификация не запрещает DELETE-запросы иметь тело сообщения, [раздел 4.3] (http://www.w3.org/Protocols/rfc2616/rfc2616-sec4.html#sec4.3), кажется, указывает, что тело должно игнорироваться серверами_, поскольку для [DELETE] нет «определенной семантики» (http://www.w3.org/Protocols/rfc2616/rfc2616-sec9.html#sec9.7) Органы-субъекты: «Сервер ДОЛЖЕН читать и пересылать тело сообщения по любому запросу; ** если метод запроса не содержит определенные семантики для тела сущности, тогда тело сообщения ДОЛЖНО проигнорироваться при обработке запроса ** «. – shelley 2013-01-09 23:49:39

+28

Обратите внимание, что многие клиенты также не могут отправить DELETE с телом. Это просто сожгло меня на Android. – 2014-08-26 20:10:42

27

Мне кажется, что RFC 2616 не указывает это.

Из разделе 4.3:

Присутствие тела сообщения в запросе сигнализируется включения Content-Length или поле заголовка Transfer-Encoding в Message-заголовкам запроса. Тело сообщения НЕ ДОЛЖНО быть включено в запрос, если спецификация метода запроса (раздел 5.1.1) не позволяет отправлять тело объекта в запросы.Сервер ДОЛЖЕН читать и пересылать тело сообщения по любому запросу; если метод запроса не включает определенную семантику для объекта-объекта, то при обработке запроса следует игнорировать сообщение-тело .

И раздел 9.7:

В УДАЛЕНИИ запросов метода, что сервер происхождения удалить ресурс идентифицированного Request-URI. Этот метод МОЖЕТ быть переопределен человеческим вмешательством (или другими средствами) на исходном сервере. Клиент не может гарантировать, что операция была выполнена, даже если код состояния , возвращенный с исходного сервера, указывает, что действие было успешно завершено. Тем не менее, сервер НЕ ДОЛЖЕН указать успех, если только в момент ответа ответа он намеревается удалить ресурс или переместить его в недоступное место .

В случае успешного ответа ДОЛЖЕН быть 200 (ОК), если ответ включает в себя объект, описывающий состояние, 202 (Accepted) не если действие не еще не принят, или 204 (No Content), если действие было принято , но ответ не включает объект.

Если запрос проходит через кэш, а Request-URI идентифицирует один или несколько в настоящее время кэшированных объектов, эти записи ДОЛЖНЫ быть считаться устаревшими. Ответы на этот метод не cacheable.c

Так что это явно не разрешено или запрещено, и есть шанс, что прокси-сервер по пути может удалить тело сообщения (хотя следует читать и пересылать его).

47

Некоторые версии Tomcat и Jetty, похоже, игнорируют тело объекта, если оно присутствует. Что может быть неприятностью, если вы намеревались его получить.

105

Последнее обновление спецификации HTTP 1.1 (RFC 7231) явно разрешает тело пакета в запросе DELETE:

Полезная нагрузка в сообщении запроса на удаление не имеет определенную семантику; отправка тела полезной нагрузки по запросу DELETE может привести к тому, что некоторые существующие реализации отклонят запрос.

35

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

Вы читаете версию 1 записи.

GET /some-resource/1 
200 OK { id:1, status:"unimportant", version:1 } 

Ваш коллега читает версию 1 записи.

GET /some-resource/1 
200 OK { id:1, status:"unimportant", version:1 } 

Ваш коллега изменяет запись и обновляет базу данных, которая обновляет версию до 2:

PUT /some-resource/1 { id:1, status:"important", version:1 } 
200 OK { id:1, status:"important", version:2 } 

Вы пытаетесь удалить запись:

DELETE /some-resource/1 { id:1, version:1 } 
409 Conflict 

Вы должны получить оптимист исключение блокировки. Перечитайте запись, посмотрите, что она важна и, возможно, не удаляет ее.

Другая причина, по которой это необходимо, - удалить несколько записей за раз (например, сетку с флажками выбора строки).

DELETE /messages 
[{id:1, version:2}, 
{id:99, version:3}] 
204 No Content 

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

Это работает в Tomcat (7.0.52) и Spring MVC (4,05), возможно более ранние версии ж тоже:

@RestController 
public class TestController { 

    @RequestMapping(value="/echo-delete", method = RequestMethod.DELETE) 
    SomeBean echoDelete(@RequestBody SomeBean someBean) { 
     return someBean; 
    } 
} 
3

В случае, если кто работает в этом тестировании вопрос, Нет, это не повсеместно поддерживается.

В настоящее время я тестирую Sahi Pro, и очень очевидно, что http DELETE вызывает полоски любых предоставленных данных тела (большой список идентификаторов для удаления навалом в зависимости от дизайна конечной точки).

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

Я уверен, что Сахи не поддерживает это, и я бы представил, что многие другие инструменты следуют за комплектом.

9

Просто голова, если вы поставляете тело в свой запрос DELETE и используете балансировщик нагрузки HTTPS Google Cloud, он отклонит ваш запрос с ошибкой 400. Я ударился головой о стену и пришел к выводу, что Google по какой-то причине считает, что запрос DELETE с телом является искаженным запросом.

4

Это не определено.

Полезная нагрузка в сообщении запроса DELETE не имеет определенной семантики; отправка тела полезной нагрузки по запросу DELETE может привести к тому, что некоторые существующие реализации отклонят запрос.
https://tools.ietf.org/html/rfc7231#page-29

Смежные вопросы