คำขอ 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"
Vinicius de Almeida

@ViniciusdeAlmeida ทรัพยากรเหล่านั้นจะไม่เหมาะสมหากคุณพยายามปฏิบัติตามมาตรฐาน REST disableและenableเป็นคำกริยา ฉันอาจต้องการใช้PATCHกับ/users/{id}จุดสิ้นสุดในกรณีนั้น
ขยี้

42

ไม่ตอบคำถาม แต่ยืนยันว่า jaxrs ช่วยให้ฉันใช้ PUT แบบไม่ใช้ร่างกายได้บ่อยแค่ไหน:

ตัวอย่างการใส่แบบไม่มีร่างกาย: ให้สิทธิ์เพิ่มเติมแก่ผู้ใช้

PUT / admin / users / {username} / permission / {permission}


2
ตรงปัญหาของฉัน! ฉันได้ข้อสรุปเดียวกัน แต่พูดอย่างเคร่งครัดสิ่งนี้ขัดแย้งกับ RFC ซึ่งแม้ว่าจะไม่ได้กล่าวถึงอย่างชัดเจน แต่ร่างกายก็เรียกว่ามีอยู่ อาจทำให้เกิดปัญหา แต่จากประสบการณ์ของฉันเว็บเซิร์ฟเวอร์ / เฟรมเวิร์กที่ทันสมัยทั้งหมดจะทำงานได้
Agoston Horvath

ฉันอยู่ในกรณีที่คล้ายกันฉันต้องการ API เพื่อเชื่อมโยงทรัพยากรที่มีอยู่กับผู้ใช้ ฉันสามารถใช้ผู้ใช้ POST /: userId / resources ที่มี resourceId ในตัว หรือค่อนข้างจะพอดีกับผู้ใช้ PUT /: userid / resources /: resourceId ความแตกต่างอย่างมากที่นี่คือ firt API ควรจะเป็น non-idempotent ดังนั้นฉันสามารถเชื่อมโยงทรัพยากรเดียวกันกับผู้ใช้สองครั้ง การโทร PUT ควรรีเซ็ตการเชื่อมโยงก่อนหน้านี้
Carmine Ingaldi

5

มาตรฐาน IETF ไม่จำเป็นต้องมีเนื้อหาแม้ว่าความยาวของเนื้อหาควรเป็น 0 หากไม่มีเนื้อหา ใช้วิธีการที่เหมาะสมกับสิ่งที่คุณทำ ถ้าคุณจะใส่ลงในรหัสให้

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

rและตัวแปรระยะไกลที่เรียกว่า

โพสต์เทียบเท่ากับ

r=f();

การใส่เทียบเท่ากับ

r=x;

และได้รับเทียบเท่ากับ

x=r;

1
นี่คือตัวอย่างที่ชัดเจนที่สุดของ PUT vs POST ที่ฉันเคยอ่านแม้ว่าจะไม่อยู่ในหัวข้อก็ตาม
ภาพลวงตาดิจิทัล

หากคำขอมีส่วนหัวความยาวของเนื้อหาแสดงว่ามีเนื้อหา มันอาจจะเป็นร่างที่ว่างเปล่า แต่ก็ยังเป็นร่างกาย ตรงกันข้ามกับคำขอที่ไม่มีส่วนหัวความยาวของเนื้อหาซึ่งไม่มีเนื้อหาเลยแม้แต่คำขอที่ว่างเปล่า ใช่แล้วคำขอ PUT ในทางเทคนิคอย่างเคร่งครัดจะต้องมีร่างกาย เสมอ.
Paul Groke

นอกจากนี้การเปรียบเทียบ POST ของคุณทำให้ฉันสับสนโดยสิ้นเชิง ถ้าฉันพยายามที่จะอยู่กับการเปรียบเทียบที่เหลือของคุณมันควรจะเหมือนกับว่าเซิร์ฟเวอร์มีint f(int* resource, int body);แล้ว POST จะเรียกใช้f(&r, x);- ซึ่งอาจทำหรือไม่ทำrอะไรก็ได้ที่เซิร์ฟเวอร์คิดว่าเหมาะสม แต่ก็ยังสามารถกลับสิ่งดังนั้น ... y = f(&r, x);อาจจะมากขึ้นเช่น
Paul Groke

0

อะไรคือการ PUT (ในความหมายของคำกริยา) บนเซิร์ฟเวอร์หากไม่มีเนื้อหา ข้อมูลจำเพาะหมายถึงเนื้อหาเป็น "นิติบุคคลที่ล้อมรอบ" แต่คำขอที่ไม่มีเนื้อหาจะไม่มีการปิดล้อมนิติบุคคลและดังนั้นจึงไม่มีอะไรที่จะวางบนเซิร์ฟเวอร์

เว้นแต่ว่าคุณไม่ต้องการใส่อะไรลงในเซิร์ฟเวอร์ซึ่งในกรณีนี้คุณอาจต้องการ DELETE แทน


1
สิ่งที่คุณใส่อาจเข้ารหัส URL แทนที่จะอยู่ในเนื้อความ
MikeT

1
PUT empty เป็นเพียงการประกาศว่าทรัพยากรที่มีข้อมูลประจำตัวที่กำหนดต้องมีอยู่บนเซิร์ฟเวอร์แม้ว่าจะไม่มีเนื้อหาใด ๆ นอกเหนือจากตัวตน นั่นคือความหมายที่แตกต่างอย่างสิ้นเชิงกับ DELETE
Imre Pühvel

สมมติว่าคุณต้องการใส่ทรัพยากร แต่ยอมรับค่าเริ่มต้นฝั่งเซิร์ฟเวอร์ทั้งหมด นั่นจะเป็นContent-Length: 0หรือ{ }ใน JSON เป็นร่างกาย?
Luke Puplett

1
คุณไม่มีไฟล์ว่างสักไฟล์เดียวในคอมพิวเตอร์ใช่ไหม
КонстантинВан

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.