Yêu cầu HTTP PUT có bắt buộc phải bao gồm phần thân không?


91

Tôi đang gặp sự cố khi tìm thông số kỹ thuật cụ thể về điều này trong tiêu chuẩn. Tôi có một ứng dụng khách HTTP không bao gồm Content-Length: 0tiêu đề khi thực hiện yêu cầu PUT mà tôi không chỉ định nội dung và một máy chủ bị nhầm lẫn bởi các yêu cầu như vậy và tôi đang tự hỏi mình nên đổ lỗi cho chương trình nào.


Tại sao bạn sẽ chỉnh sửa một câu hỏi từ năm 2009 nếu tôi có thể hỏi?
zmuci

@zmuci Để có định dạng tốt hơn?
Константин Ван

Câu trả lời:


81

Các yêu cầu HTTP có phần thân nếu chúng có tiêu đề Độ dài Nội dung hoặc Mã hóa Truyền ( RFC 2616 4.3 ). Nếu yêu cầu không có, nó không có nội dung và máy chủ của bạn phải xử lý nó như vậy.

Điều đó nói rằng việc yêu cầu PUT không có nội dung là điều bất thường và vì vậy nếu tôi đang thiết kế một khách hàng thực sự muốn gửi nội dung trống, tôi sẽ chuyển Nội dung-Độ dài: 0. Thật vậy, tùy thuộc vào cách đọc ĐĂNG và định nghĩa phương pháp PUT ( RFC 2616 9.5, 9.6 ) người ta có thể tranh luận rằng phần thân được ngụ ý là bắt buộc - nhưng một cách hợp lý để xử lý không phần thân nào là giả sử phần thân có độ dài bằng không.


Như mã trạng thái HTTP 200 (“OK”), 201 (“Đã tạo”) và 204 (“Không có nội dung”) ngụ ý, một PUTyêu cầu về cơ bản là để tạo hoặc cập nhật tệp trên máy chủ. Và không có gì bất hợp pháp về việc một tệp trống, phải không?
Константин Ван


5
@bdonlan, bạn đã nói rằng PUT có phần thân trống là không bình thường, nhưng nếu tôi muốn bật hoặc tắt một người dùng, tôi sẽ không cần phần thân theo yêu cầu của mình, thực tế các yêu cầu PUT có thể là "/ users / {id} / enable" hoặc "/ users / {id} / disable".
Vinicius de Almeida

@ViniciusdeAlmeida Những tài nguyên đó sẽ không phù hợp nếu bạn đang cố gắng tuân thủ các tiêu chuẩn REST. disableenablelà động từ. Tôi có lẽ muốn sử dụng PATCHtrên /users/{id}thiết bị đầu cuối trong trường hợp đó.
nghiền nát

42

Không trả lời câu hỏi, nhưng khẳng định cách jaxrs cho phép tôi sử dụng thường xuyên PUT không thân:

Ví dụ về bodyless put: Cấp cho người dùng một quyền bổ sung.

PUT / admin / users / {username} / allow / {allow}


2
Chính xác là vấn đề của tôi! Tôi đã đi đến kết luận tương tự. Nhưng nói một cách chính xác, điều này đi ngược lại với RFC, trong đó, mặc dù không được đề cập rõ ràng, nhưng body được coi là hiện có. Nó có thể gây ra sự cố, nhưng theo kinh nghiệm của tôi, tất cả các máy chủ / khuôn khổ web hiện đại sẽ hoạt động.
Agoston Horvath

Tôi đang ở trong trường hợp tương tự, tôi cần một API để liên kết tài nguyên hiện có với người dùng. Tôi có thể sử dụng POST người dùng /: userId / resources với resourceId trong phần thân. Hay đúng hơn nó sẽ phù hợp với người dùng PUT /: userid / resources /: resourceId. Sự khác biệt lớn ở đây là API firt được cho là không phải là idmpotent, vì vậy tôi có thể liên kết cùng một tài nguyên với một người dùng hai lần. lệnh gọi PUT sẽ đặt lại liên kết trước đó
Carmine Ingaldi

5

Tiêu chuẩn IETF không yêu cầu nội dung, mặc dù độ dài nội dung phải bằng 0 nếu không có nội dung. Sử dụng phương pháp phù hợp với công việc bạn đang làm. Nếu bạn đặt nó vào mã,

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

và một biến từ xa được gọi r.

Một bài đăng tương đương với

r=f();

Một cú đặt tương đương với

r=x;

và nhận được tương đương với

x=r;

1
Đây là ví dụ rõ ràng nhất của PUT vs POST mà tôi từng đọc, mặc dù ra khỏi chủ đề
ảo ảnh kỹ thuật số

Nếu yêu cầu có tiêu đề Độ dài Nội dung, thì yêu cầu đó có nội dung. Nó có thể là một cơ thể trống rỗng, nhưng vẫn là một cơ thể. Ngược lại với yêu cầu không có tiêu đề Độ dài nội dung, không có phần nội dung nào, thậm chí không có phần trống. Vì vậy, có, một yêu cầu PUT, về mặt kỹ thuật, nghiêm ngặt, phải có một phần thân. Luôn luôn.
Paul Groke

Ngoài ra, sự tương tự POST của bạn hoàn toàn khó hiểu đối với tôi. Nếu tôi cố gắng tiếp tục với phần còn lại của sự tương tự của bạn, nó sẽ giống như máy chủ có int f(int* resource, int body);và sau đó POST sẽ gọi f(&r, x);- điều này có thể làm hoặc không làm với rbất kỳ điều gì mà máy chủ cho là phù hợp. Nhưng nó cũng có thể trả lại nội dung, vì vậy ... có thể giống hơn y = f(&r, x);.
Paul Groke

0

Điều gì đang được PUT (theo nghĩa động từ) vào máy chủ nếu không có nội dung? Đặc tả đề cập đến nội dung là "thực thể kèm theo", nhưng một yêu cầu không có nội dung sẽ không có thực thể kèm theo và do đó không có gì để đưa lên máy chủ.

Tất nhiên, trừ khi bạn không muốn PUT không có gì lên máy chủ, trong trường hợp đó bạn có thể muốn XÓA thay thế.


1
những gì bạn đưa có thể được mã hóa URL chứ không phải trong nội dung
MikeT

1
PUT rỗng chỉ là khai báo rằng tài nguyên có danh tính nhất định phải tồn tại trên máy chủ mặc dù nó không có nội dung nào ngoài bản thân danh tính. Đó là ngữ nghĩa hoàn toàn khác với DELETE.
Imre Pühvel

Hãy tưởng tượng bạn muốn PUT một tài nguyên nhưng chấp nhận tất cả các giá trị mặc định phía máy chủ. Đó sẽ là Content-Length: 0hay { }trong JSON làm phần thân?
Luke Puplett,

1
Vì vậy, bạn không có một tệp trống nào trên máy tính của mình, phải không?
Константин Ван

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.