Чи потрібен запит 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.