Чи потрібен запит HTTP PUT, щоб включити тіло?


92

Я маю проблеми з пошуком певної специфікації цього в стандарті. У мене є клієнт HTTP, який не включає Content-Length: 0заголовок при виконанні запиту PUT, де я не вказую тіло, і сервер, який заплутується від таких запитів, і мені цікаво, в якій програмі я повинен звинувачувати.


Чому ви редагуєте питання з 2009 року, якщо я можу запитати?
zmuci

@zmuci Для кращого форматування?
Константин Ван

Відповіді:


83

Запити HTTP мають тіло, якщо вони мають заголовок Content-Length або Transfer-Encoding ( RFC 2616 4.3 ). Якщо запит не має ні того, ні іншого, він не має тіла, і ваш сервер повинен розглядати його як такий.

Тим не менш, незвично для запиту PUT не мати жодного тіла, і тому, якщо я розробляв клієнта, який дійсно хотів надіслати порожнє тіло, я б передав Content-Length: 0. Дійсно, залежно від прочитаного POST і визначення методів PUT ( RFC 2616 9.5, 9.6 ) можна стверджувати, що тіло передбачається необхідним, але розумним способом обробки жодного тіла було б прийняти тіло нульової довжини.


Як передбачається код стану HTTP 200 (“ОК”), 201 (“Створений”) та 204 (“Без вмісту”), в PUTосновному запит на створення або оновлення файлу на сервері. І немає нічого незаконного у тому, що файл порожній, чи не так?
Константин Ван


5
@bdonlan ви сказали, що PUT з порожнім тілом є незвичним, але якщо я хочу ввімкнути або вимкнути користувача, мені не знадобиться тіло на мій запит, насправді запити PUT можуть бути "/ users / {id} / enable" або "/ users / {id} / disable".
Вініцій де Альмейда,

@ViniciusdeAlmeida Ці ресурси не будуть доречними, якщо ви намагаєтесь дотримуватися стандартів REST. disableі enableє дієсловами. Я б, мабуть, віддав перевагу використовувати PATCHв /users/{id}кінцевій точці в цьому випадку.
розчавити

42

Не відповідаючи на питання, але стверджуючи, як jaxrs дозволяє мені часто використовувати безтілесні PUT:

Приклад безтурботного ставлення: Дайте користувачеві додатковий дозвіл.

PUT / admin / users / {username} / дозвіл / {дозвіл}


2
Саме моя проблема! Я дійшов такого ж висновку. Але, строго кажучи, це суперечить RFC, де, хоча це не зазначено прямо, орган називається існуючим. Це може спричинити проблеми, але, на мій досвід, усі сучасні веб-сервери / фреймворки будуть працювати.
Агостон Горват

Я перебуваю в подібному випадку, мені потрібен API, щоб пов’язати існуючий ресурс із користувачем. Я міг би використовувати POST users /: userId / resources з resourceId у тілі. Вірніше, він підходить для користувачів PUT /: userid / resources /: resourceId. Велика різниця тут полягає в тому, що API firt повинен бути неідемпотентним, тому я міг би прив'язати один і той же ресурс до користувача двічі. дзвінок PUT повинен скинути попередню асоціацію
Carmine Ingaldi

5

Основний текст не вимагається стандартом IETF, хоча довжина вмісту повинна бути 0, якщо його немає. Використовуйте метод, який підходить для того, що ви робите. Якби ви ввели це в код, дано

int x;
int f(){ return x; }

і віддалена змінна з назвою r.

Публікація еквівалентна

r=f();

Пут еквівалентний

r=x;

і отримання еквівалентно

x=r;

1
Це найяскравіший приклад PUT проти POST, який я коли-небудь читав, хоча і не в темі
цифрова ілюзія

Якщо запит має заголовок Content-Length, то він має тіло. Це може бути порожнє тіло, але все-таки тіло. На відміну від запиту без заголовка Content-Length, який взагалі не має жодного тіла, навіть порожнього. Тож так, запит PUT, технічно, суворо, повинен мати тіло. Завжди.
Пол Гроук,

Також ваша аналогія POST мене абсолютно бентежить. Якщо я спробую дотримуватися решти вашої аналогії, це має бути більше схоже на те, що на сервері є, int f(int* resource, int body);а потім буде викликати POST f(&r, x);- що може робити або не робити rте, що сервер вважає за потрібне. Але це може також повернути речі, тому ... можливо, більше подобається y = f(&r, x);.
Пол Гроук,

0

Що ставиться (у дієслівному значенні) на сервер, якщо немає вмісту? Специфікації відносяться до змісту , як «вкладеної сутність», але запит без змісту не матиме включений об'єкт, і , отже , нічого поставити на сервері.

Якщо, звичайно, ви не хочете ВСТАНОВИТИ нічого на сервер, і в цьому випадку ви, напевно, захочете видалити.


1
що ваше розміщення може бути закодованим URL, а не в тілі
MikeT

1
PUT empty - це просто заява про те, що ресурс із заданою ідентифікацією повинен існувати на сервері, хоча він не має вмісту, крім самої ідентифікації. Це зовсім інша семантика від DELETE.
Імре Пювель,

Уявіть, що ви хочете ВСТАВИТИ ресурс, але прийняти всі стандартні значення на стороні сервера. Це буде Content-Length: 0або { }в JSON як тіло?
Люк Пуплетт

1
Тож у вас на комп’ютері немає жодного порожнього файлу , правда?
Константин Ван

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