เป็นไปได้ไหมที่จะแคชวิธี POST ใน HTTP?


152

ด้วยซีแมนทิกส์การแคชที่ง่ายมาก: ถ้าพารามิเตอร์เหมือนกัน (และแน่นอนเหมือนกัน) จากนั้นก็ถือว่าเป็น Hit เป็นไปได้ไหม แนะนำ?

คำตอบ:


93

RFC 2616 ที่สอดคล้องกันในส่วน 9.5 (POST) อนุญาตให้แคชการตอบสนองต่อข้อความ POST หากคุณใช้ส่วนหัวที่เหมาะสม

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

หมายเหตุว่า RFC เดียวกันระบุไว้อย่างชัดเจนในมาตรา 13 (แคชใน HTTP) ที่แคชต้องโมฆะนิติบุคคลที่สอดคล้องกันหลังจาก POST คำขอ

วิธีการ HTTP บางอย่างต้องทำให้แคชใช้งานไม่ได้ นี่เป็นเอนทิตีที่อ้างถึงโดย Request-URI หรือโดยส่วนหัว Location หรือ Content-Location (ถ้ามี) วิธีการเหล่านี้คือ:

  - PUT
  - DELETE
  - POST

ยังไม่ชัดเจนสำหรับฉันว่าข้อกำหนดเหล่านี้ช่วยให้การแคชมีความหมายได้อย่างไร

สิ่งนี้ยังสะท้อนและชี้แจงเพิ่มเติมในRFC 7231 (มาตรา 4.3.3) ซึ่งล้าสมัย RFC 2616

การตอบสนองต่อคำขอ POST สามารถแคชได้เมื่อมี
ข้อมูลความสดใหม่ที่ชัดเจน (ดูหัวข้อ 4.2.1 จาก [RFC7234])
อย่างไรก็ตามการแคช POST ไม่ได้นำไปใช้อย่างกว้างขวาง สำหรับกรณีที่เซิร์ฟเวอร์ต้นทางต้องการให้ลูกค้าสามารถแคชผลลัพธ์ของ POST ด้วยวิธีที่สามารถนำกลับมาใช้ใหม่ในภายหลัง GET เซิร์ฟเวอร์ต้นทางอาจส่งการตอบสนอง 200 (OK) ที่มีผลลัพธ์และตำแหน่งเนื้อหา ฟิลด์ส่วนหัวที่มีค่าเดียวกับ URI คำขอที่มีประสิทธิภาพของ POST (ส่วน 3.1.4.2)

ตามนี้ผลลัพธ์ของ POST ที่ถูกแคช (หากความสามารถนี้ถูกระบุโดยเซิร์ฟเวอร์) สามารถนำมาใช้เป็นผลลัพธ์ของการร้องขอ GET สำหรับ URI เดียวกัน


1
ส่วนนี้ใช้กับแคชระดับกลาง (เช่นพร็อกซีเซิร์ฟเวอร์แคช) ไม่ใช่เซิร์ฟเวอร์ต้นทาง
David Z

2
เซิร์ฟเวอร์ต้นทางเป็นนายหน้าระหว่าง HTTP และแอปพลิเคชันที่จัดการคำขอ POST แอปพลิเคชันอยู่นอกเหนือขอบเขต HTTP และสามารถทำสิ่งใดก็ได้ที่ต้องการ หากการแคชมีความหมายสำหรับคำขอ POST เฉพาะนั้นสามารถแคชได้มากเท่าที่ระบบปฏิบัติการสามารถแคชคำขอดิสก์ได้
Diomidis Spinellis

2
อีกครั้ง, คำสั่งของคุณว่าการแคชคำขอ POST จะไม่เป็น HTTP, ผิด โปรดดูคำตอบของ reBoot สำหรับรายละเอียด มันไม่ได้มีประโยชน์มากนักหากจะมีคำตอบที่ผิดปรากฏขึ้นที่ด้านบน แต่นั่นคือวิธีการทำงานของประชาธิปไตย หากคุณเห็นด้วยกับ reBoot มันจะดีถ้าคุณแก้ไขคำตอบของคุณ
Eugene Beresovsky

2
Eugene เราสามารถเห็นด้วยว่าก) POST ควรทำให้เอนทิตีแคช (ต่อมาตรา 13.10) เป็นโมฆะดังนั้นเช่น GET ที่ตามมาจะต้องดึงสำเนา fersh และ b) เพื่อให้การตอบสนองของ POST นั้นถูกแคช (ต่อส่วน 9.5) ดังนั้นเช่น POST ที่ตามมาสามารถรับการตอบกลับแบบเดียวกันได้หรือไม่
Diomidis Spinellis

3
นี่คือการชี้แจงโดย HTTPbis; ดูmnot.net/blog/2012/09/24/caching_POSTสำหรับข้อมูลสรุป
Mark Nottingham

68

ตามที่ RFC 2616 มาตรา 9.5:

"วิธีการตอบสนองต่อ POST ไม่สามารถแคชได้เว้นแต่จะมีคำตอบรวมถึงการควบคุมแคชหรือฟิลด์ส่วนหัวหมดอายุ"

ดังนั้นใช่คุณสามารถแคชคำขอการตอบสนอง POST แต่ถ้ามันมาพร้อมกับส่วนหัวที่เหมาะสม ในกรณีส่วนใหญ่คุณไม่ต้องการแคชการตอบสนอง แต่ในบางกรณี - เช่นถ้าคุณไม่ได้บันทึกข้อมูลใด ๆ บนเซิร์ฟเวอร์ - มันเหมาะสมอย่างยิ่ง

หมายเหตุอย่างไรก็ตามเบราว์เซอร์จำนวนมากรวมถึง Firefox 3.0.10 ปัจจุบันจะไม่แคชการตอบสนอง POST โดยไม่คำนึงถึงส่วนหัว IE ทำงานอย่างชาญฉลาดมากขึ้นในส่วนนี้

ตอนนี้ฉันต้องการขจัดความสับสนเกี่ยวกับ RFC 2616 S. 13.10 วิธีการโพสต์ใน URI ไม่ได้ "ทำให้ทรัพยากรสำหรับแคช" เป็นโมฆะตามที่บางคนระบุไว้ที่นี่ มันทำให้รุ่นที่แคชไว้ก่อนหน้านี้ของ URI เก่าถึงแม้ว่าส่วนหัวของการควบคุมแคชระบุความสดของระยะเวลานาน


2
+1 reBoot ขอบคุณสำหรับการอธิบายปัญหาส่วนหัวและแก้ไขข้อความผิดพลาดที่เกี่ยวข้องกับ 13.10 น่าแปลกใจที่คำตอบที่ผิดเหล่านั้นได้รับคะแนนโหวตจำนวนมาก
Eugene Beresovsky

3
อะไรคือความแตกต่างระหว่าง "ทำให้ทรัพยากรสำหรับแคช" และ "ทำให้ URI รุ่นเก่าแล้ว" คุณกำลังบอกว่าเซิร์ฟเวอร์ได้รับอนุญาตให้แคชการตอบสนอง POST แต่ลูกค้าอาจจะไม่?
Gili

1
"การสร้างเวอร์ชันเก่าของ URI ที่เก็บไว้ในแคช" จะมีผลกับที่คุณใช้ URI GETและPOSTคำขอเดียวกัน หากคุณเป็นแคชนั่งอยู่ระหว่างไคลเอนต์และเซิร์ฟเวอร์คุณจะเห็นGET /fooและแคชการตอบสนอง ถัดไปคุณจะเห็นว่าPOST /fooคุณจะต้องทำให้การตอบสนองที่แคชไว้GET /fooใช้POSTไม่ได้แม้ว่าการตอบกลับจะไม่รวมส่วนหัวของการควบคุมแคชใด ๆเพราะเป็น URI เดียวกันดังนั้นถัดไปGET /fooจะต้องทำการตรวจสอบความถูกต้องอีกครั้ง สด (หากคุณไม่ได้เห็นPOST /fooคำขอ)
Stephen Connolly

But in some cases - such as if you are not saving any data on the server - it's entirely appropriate.. POST API นั้นมีจุดเริ่มต้นอย่างไร?
Siddhartha

33

โดยรวม:

โดยทั่วไปโพสต์ไม่ได้ดำเนินการ idempotent ดังนั้นคุณไม่สามารถใช้แคชได้ GET ควรเป็นการดำเนินการ idempotent ดังนั้นจึงมักใช้สำหรับการแคช

โปรดดูมาตรา 9.1 ของHTTP 1.1 RFC 2616 เอส 9.1

นอกเหนือจากความหมายของวิธีการ GET:

วิธีการโพสต์ตัวเองมีความหมายหมายถึงการโพสต์บางสิ่งบางอย่างไปยังทรัพยากร POST ไม่สามารถแคชได้เพราะถ้าคุณทำบางสิ่งบางอย่างเมื่อเทียบกับสองครั้งเทียบกับสามครั้งแล้วคุณจะเปลี่ยนทรัพยากรของเซิร์ฟเวอร์ในแต่ละครั้ง คำขอแต่ละเรื่องมีความสำคัญและควรส่งไปยังเซิร์ฟเวอร์

วิธีการ PUT นั้นหมายถึงการใส่หรือสร้างทรัพยากร เป็นการดำเนินการ idempotent แต่จะไม่ใช้สำหรับการแคชเนื่องจากอาจมี DELETE เกิดขึ้นในระหว่างนี้

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

เกี่ยวกับการแคชฝั่งไคลเอ็นต์:

เว็บเบราว์เซอร์จะส่งต่อคำขอของคุณเสมอแม้ว่าจะมีการตอบสนองจากการดำเนินการ POST ก่อนหน้า ตัวอย่างเช่นคุณอาจส่งอีเมลโดยใช้ Gmail แยกกันสองสามวัน อาจเป็นหัวเรื่องและเนื้อหาเดียวกัน แต่ควรส่งอีเมลทั้งสองฉบับ

เกี่ยวกับการแคชพร็อกซี:

พร็อกซีเซิร์ฟเวอร์ HTTP ที่ส่งต่อข้อความของคุณไปยังเซิร์ฟเวอร์จะไม่แคชอะไรเลยนอกจากคำขอ GET หรือ HEAD

เกี่ยวกับการแคชเซิร์ฟเวอร์:

เซิร์ฟเวอร์โดยค่าเริ่มต้นจะไม่จัดการคำขอ POST โดยอัตโนมัติผ่านการตรวจสอบแคช แต่แน่นอนว่าคำขอ POST สามารถส่งไปยังแอปพลิเคชันหรือ Add-in ของคุณและคุณสามารถมีแคชของคุณเองที่คุณอ่านเมื่อพารามิเตอร์เหมือนกัน

การทำให้ทรัพยากรใช้ไม่ได้:

การตรวจสอบHTTP 1.1 RFC 2616 S. 13.10แสดงว่าเมธอด POST ควรทำให้ทรัพยากรสำหรับการแคชใช้ไม่ได้


9
"โดยทั่วไป POST ไม่ใช่การดำเนินการ idempotent ดังนั้นคุณไม่สามารถใช้เพื่อแคช" นั่นเป็นเพียงความผิดและไม่สมเหตุสมผลโปรดดูคำตอบของ reBoot สำหรับรายละเอียด น่าเสียดายที่ฉันยังไม่สามารถลงคะแนนไม่เช่นนั้นฉันก็จะได้
Eugene Beresovsky

1
ยูจีน: ฉันเปลี่ยน "ไม่ใช่" เป็น "อาจไม่"
Brian R. Bondy

1
ขอบคุณไบรอันฟังดูดีกว่า ปัญหาของฉันกับ "POST ไม่ใช่ idemp ของคุณ -> ไม่สามารถแคช" ได้ - และฉันไม่ได้ทำให้ชัดเจนเพียงพอ - แม้ว่าการดำเนินการไม่ได้เป็น idempotent ที่ไม่ได้หมายความว่าจะไม่แคช ฉันเดาคำถามคือคุณกำลังดูจากมุมมองของเซิร์ฟเวอร์ที่ให้บริการข้อมูลและรู้ความหมายของมันหรือคุณกำลังดูจากด้านรับ (ไม่ว่าจะเป็นแคชพร็อกซีเป็นต้นหรือลูกค้า) . หากเป็นไคลเอนต์ / พร็อกซี pov ฉันเห็นด้วยกับโพสต์ของคุณทั้งหมด ถ้าเป็นเซิร์ฟเวอร์ pov, ถ้าเซิร์ฟเวอร์แจ้งว่า: "client can cache", ไคลเอ็นต์สามารถแคชได้
Eugene Beresovsky

1
ยูจีน: ถ้ามันสร้างความแตกต่างไม่ว่าจะถูกเรียกหนึ่งครั้งหรือ 5 ครั้งเช่นถ้าคุณโพสต์ข้อความไปยังรายการคุณต้องการให้การโทรนั้นถึงเซิร์ฟเวอร์ 5 ครั้งใช่ไหม? และคุณไม่ต้องการแคชดังนั้นจึงไม่ตีเซิร์ฟเวอร์ใช่ไหม เพราะมีผลข้างเคียงที่สำคัญ
Brian R. Bondy

[ต่อไป] ฉันยังไม่ได้ตัดสินใจว่าเซิร์ฟเวอร์ควรส่งแคชที่อนุญาตให้หมดอายุส่วนหัวเท่านั้นหากการดำเนินการ idempotent แต่มันก็สมเหตุสมผลดีฉันคิดว่า [เพิ่งเห็นการตอบสนองของคุณ]: เห็นด้วยดังนั้นฉันคิดว่าฉันตัดสินใจ: เซิร์ฟเวอร์ควรส่งสัญญาณการแคชในกรณีที่ idempotency - และนั่นอาจเป็น POST ด้วยโดยเฉพาะอย่างยิ่งเมื่อพิจารณาถึงความต้องการ X-HTTP-Method-Override ใน บางกรณี.
Eugene Beresovsky

6

หากคุณแคชการตอบสนอง POST จะต้องเป็นไปตามทิศทางของเว็บแอปพลิเคชัน นี่คือสิ่งที่มีความหมายโดย "การตอบสนองต่อวิธีนี้จะไม่สามารถเข้าถึงได้เว้นแต่ว่าการตอบสนองจะรวมถึงฟิลด์ส่วนหัวการควบคุมแคชหรือการหมดอายุที่เหมาะสม"

หนึ่งสามารถสันนิษฐานได้อย่างปลอดภัยว่าแอปพลิเคชันซึ่งรู้ว่าผลลัพธ์ของ POST นั้นเป็น idempotent หรือไม่ตัดสินใจว่าจะแนบส่วนหัวควบคุมแคชที่จำเป็นและเหมาะสมหรือไม่ หากส่วนหัวที่แนะนำการแคชได้รับอนุญาตมีอยู่แอปพลิเคชันจะบอกคุณว่า POST คือ super-GET ในความเป็นจริง การใช้ POST นั้นจำเป็นเพียงเพราะปริมาณของข้อมูลที่ไม่จำเป็นและไม่เกี่ยวข้อง (สำหรับการใช้ URI เป็นคีย์แคช) ข้อมูลที่จำเป็นในการดำเนินการ idempotent

การติดตาม GET สามารถให้บริการได้จากแคชภายใต้สมมติฐานนี้

แอปพลิเคชันที่ล้มเหลวในการแนบส่วนหัวที่จำเป็นและถูกต้องเพื่อแยกความแตกต่างระหว่างการตอบสนอง POST ที่ถอดออกได้และไม่สามารถเข้าถึงได้เป็นความผิดสำหรับผลการแคชที่ไม่ถูกต้อง

ที่กล่าวว่าแต่ละโพสต์ที่เข้าชมแคชต้องการการตรวจสอบความถูกต้องโดยใช้ส่วนหัวที่มีเงื่อนไข สิ่งนี้จำเป็นในการรีเฟรชเนื้อหาแคชเพื่อหลีกเลี่ยงผลลัพธ์ของ POST ที่จะไม่ถูกสะท้อนในการตอบสนองต่อการร้องขอจนกระทั่งหลังจากอายุการใช้งานของวัตถุหมดอายุ


4

Mark Nottingham วิเคราะห์เมื่อเป็นไปได้ที่จะแคชการตอบสนองของ POST โปรดทราบว่าคำขอต่อมาที่ต้องการใช้ประโยชน์จากการแคชจะต้องเป็นคำขอ GET หรือ HEAD ดูเพิ่มเติมที่http semantics

โพสต์ไม่เกี่ยวข้องกับการเป็นตัวแทนของรัฐที่ระบุ 99 ครั้งจาก 100 อย่างไรก็ตามมีกรณีหนึ่งที่มัน; เมื่อเซิร์ฟเวอร์ไม่สามารถพูดได้ว่าการตอบสนอง POST นี้เป็นการแสดง URI ของเซิร์ฟเวอร์โดยการตั้งค่าส่วนหัวของเนื้อหา - สถานที่ซึ่งเป็นสิ่งเดียวกันกับคำขอของ URI เมื่อสิ่งนั้นเกิดขึ้นการตอบสนอง POST ก็เหมือนกับการตอบสนอง GET กับ URI เดียวกัน สามารถแคชและนำกลับมาใช้ใหม่ - แต่สำหรับคำขอ GET ในอนาคตเท่านั้น

https://www.mnot.net/blog/2012/09/24/caching_POST


4

หากคุณสงสัยว่าคุณสามารถแคชคำขอโพสต์และลองค้นคว้าคำตอบของคำถามนั้นได้หรือไม่คุณอาจประสบความสำเร็จไม่ได้ เมื่อค้นหา "คำขอโพสต์แคช" ผลลัพธ์แรกคือคำถาม StackOverflow

คำตอบคือส่วนผสมที่สับสนว่าการแคชควรทำงานอย่างไรการแคชทำงานตาม RFC อย่างไรการแคชควรทำงานตาม RFC อย่างไรและการแคชทำงานอย่างไรในทางปฏิบัติ เริ่มจาก RFC เดินผ่านการสาธิตว่าเบราว์เซอร์ทำงานอย่างไรจากนั้นพูดคุยเกี่ยวกับ CDNs, GraphQL และประเด็นอื่น ๆ ที่เกี่ยวข้อง

RFC 2616

ตาม RFC คำขอ POST จะต้องทำให้แคชใช้ไม่ได้:

13.10 Invalidation After Updates or Deletions

..

Some HTTP methods MUST cause a cache to invalidate an entity. This is
either the entity referred to by the Request-URI, or by the Location
or Content-Location headers (if present). These methods are:
  - PUT
  - DELETE
  - POST

ภาษานี้แสดงว่าคำขอ POST ไม่สามารถแคชได้ แต่นั่นไม่เป็นความจริง (ในกรณีนี้) แคชไม่ถูกต้องสำหรับข้อมูลที่เก็บไว้ก่อนหน้านี้เท่านั้น RFC (ดูเหมือนจะ) ชี้แจงอย่างชัดเจนว่าใช่คุณสามารถแคชPOSTคำขอ:

9.5 POST

..

Responses to this method are not cacheable, unless the response
includes appropriate Cache-Control or Expires header fields. However,
the 303 (See Other) response can be used to direct the user agent to
retrieve a cacheable resource.

แม้จะมีภาษานี้การตั้งค่าCache-Controlจะต้องไม่POSTส่งคำขอต่อไปยังทรัพยากรเดียวกัน POSTต้องส่งคำขอไปยังเซิร์ฟเวอร์:

13.11 Write-Through Mandatory

..

All methods that might be expected to cause modifications to the
origin server's resources MUST be written through to the origin
server. This currently includes all methods except for GET and HEAD.
A cache MUST NOT reply to such a request from a client before having
transmitted the request to the inbound server, and having received a
corresponding response from the inbound server. This does not prevent
a proxy cache from sending a 100 (Continue) response before the
inbound server has sent its final reply.

มันสมเหตุสมผลแค่ไหน? คุณไม่ได้แคPOSTร้องขอคุณกำลังแคชทรัพยากร

เนื้อหาการตอบสนอง POST สามารถแคชสำหรับการร้องขอ GET ต่อมาไปยังทรัพยากรเดียวกัน ตั้งค่าLocationหรือContent-Locationส่วนหัวในการตอบสนอง POST เพื่อสื่อสารทรัพยากรที่ร่างกายเป็นตัวแทน ดังนั้นวิธีเดียวที่ถูกต้องทางเทคนิคในการแคชคำขอ POST สำหรับ GETs ต่อไปคือทรัพยากรเดียวกัน

คำตอบที่ถูกต้องคือ:

  • "ใช่ RFC อนุญาตให้คุณแคชคำขอ POST เพื่อรับ GET ต่อไปในแหล่งข้อมูลเดียวกัน"
  • "ไม่ RFC ไม่อนุญาตให้คุณแคชคำขอ POST สำหรับ POST ที่ตามมาเนื่องจาก POST ไม่ใช่ idempotent และต้องเขียนผ่านไปยังเซิร์ฟเวอร์"

แม้ว่า RFC อนุญาตให้แคชคำขอไปยังทรัพยากรเดียวกัน แต่ในทางปฏิบัติเบราว์เซอร์และ CDNs ไม่ได้ใช้พฤติกรรมนี้และไม่อนุญาตให้คุณแคชคำขอ POST

แหล่งที่มา:

การสาธิตพฤติกรรมของเบราว์เซอร์

รับตัวอย่างแอ็พพลิเคชัน JavaScript ต่อไปนี้ (index.js):

const express = require('express')
const app = express()

let count = 0

app
    .get('/asdf', (req, res) => {
        count++
        const msg = `count is ${count}`
        console.log(msg)
        res
            .set('Access-Control-Allow-Origin', '*')
            .set('Cache-Control', 'public, max-age=30')
            .send(msg)
    })
    .post('/asdf', (req, res) => {
        count++
        const msg = `count is ${count}`
        console.log(msg)
        res
            .set('Access-Control-Allow-Origin', '*')
            .set('Cache-Control', 'public, max-age=30')
            .set('Content-Location', 'http://localhost:3000/asdf')
            .set('Location', 'http://localhost:3000/asdf')
            .status(201)
            .send(msg)
    })
    .set('etag', false)
    .disable('x-powered-by')
    .listen(3000, () => {
        console.log('Example app listening on port 3000!')
    })

และได้รับตัวอย่างหน้าเว็บต่อไปนี้ (index.html):

<!DOCTYPE html>
<html>

<head>
    <script>
        async function getRequest() {
            const response = await fetch('http://localhost:3000/asdf')
            const text = await response.text()
            alert(text)
        }
        async function postRequest(message) {
            const response = await fetch(
                'http://localhost:3000/asdf',
                {
                    method: 'post',
                    body: { message },
                }
            )
            const text = await response.text()
            alert(text)
        }
    </script>
</head>

<body>
    <button onclick="getRequest()">Trigger GET request</button>
    <br />
    <button onclick="postRequest('trigger1')">Trigger POST request (body 1)</button>
    <br />
    <button onclick="postRequest('trigger2')">Trigger POST request (body 2)</button>
</body>

</html>

ติดตั้ง NodeJS, Express และเริ่มต้นแอปพลิเคชัน JavaScript เปิดหน้าเว็บในเบราว์เซอร์ของคุณ ลองใช้สถานการณ์ต่าง ๆ เพื่อทดสอบพฤติกรรมของเบราว์เซอร์:

  • การคลิก "เรียกใช้ GET ขอ" จะแสดง "นับ" เดียวกันทุกครั้ง (การแคช HTTP ทำงาน)
  • การคลิก "คำขอเรียกใช้ POST" จะเรียกใช้การนับที่แตกต่างกันทุกครั้ง (การแคช HTTP สำหรับ POST ไม่ทำงาน)
  • การคลิก "ขอเรียกใช้ GET", "เรียกใช้คำขอ POST" และ "ขอเรียกใช้ GET" แสดงคำขอ POST ทำให้แคชคำขอของ GET ใช้ไม่ได้
  • คลิกที่ "Trigger POST Request" จากนั้น "Trigger GET request" แสดงว่าเบราว์เซอร์จะไม่ทำการแคช POST สำหรับการร้องขอ GET ต่อมาแม้ว่า RFC จะได้รับอนุญาต

สิ่งนี้แสดงให้เห็นว่าแม้ว่าคุณจะสามารถตั้งค่าCache-ControlและContent-Locationตอบสนองส่วนหัว แต่ก็ไม่มีวิธีที่จะทำให้แคชของเบราว์เซอร์เป็นคำขอ HTTP POST

ฉันต้องทำตาม RFC หรือไม่

ลักษณะการทำงานของเบราว์เซอร์ไม่สามารถกำหนดค่าได้ แต่หากคุณไม่ใช่เบราว์เซอร์คุณไม่จำเป็นต้องผูกพันตามกฎของ RFC

หากคุณกำลังเขียนรหัสแอปพลิเคชันไม่มีอะไรที่ห้ามไม่ให้คุณทำการแคชคำขอ POST (pseudocode) อย่างชัดเจน:

if (cache.get('hello')) {
  return cache.get('hello')
} else {
  response = post(url = 'http://somewebsite/hello', request_body = 'world')
  cache.put('hello', response.body)
  return response.body
}

CDNs พร็อกซีและเกตเวย์ไม่จำเป็นต้องทำตาม RFC เช่นกัน ตัวอย่างเช่นถ้าคุณใช้ fastly เป็น CDN ของคุณ fastly ช่วยให้คุณสามารถเขียนVCL กำหนดเองตรรกะในการร้องขอ POST แคช

ฉันควรแคชคำขอ POST หรือไม่

คำขอ POST ของคุณควรถูกแคชหรือไม่ขึ้นอยู่กับบริบท

ตัวอย่างเช่นคุณอาจสืบค้น Elasticsearch หรือ GraphQL โดยใช้ POST โดยที่การสืบค้นพื้นฐานของคุณคือ idempotent ในกรณีเหล่านั้นอาจหรือไม่เหมาะสมที่จะแคชการตอบสนองขึ้นอยู่กับกรณีการใช้งาน

ใน RESTful API คำขอ POST มักจะสร้างทรัพยากรและไม่ควรแคช นี่เป็นความเข้าใจของ RFC เกี่ยวกับ POST ว่าไม่ใช่การทำงานของ idempotent

GraphQL

หากคุณกำลังใช้ GraphQL และต้องแคช HTTP ทั่ว CDNs และเบราว์เซอร์ให้พิจารณาว่าการส่งคำสั่งโดยใช้วิธีการ GETตรงตามความต้องการของคุณแทนการโพสต์ เบราว์เซอร์และ CDN ต่างกันอาจมีข้อจำกัดความยาวของ URI ที่แตกต่างกัน แต่การดำเนินการให้ปลอดภัย (รายการที่อนุญาตพิเศษ) เป็นแนวทางปฏิบัติที่ดีที่สุดสำหรับแอป GraphQL ที่ใช้งานภายนอกอาจทำให้ URIs สั้นลง


3

หากเป็นสิ่งที่ไม่เปลี่ยนแปลงข้อมูลบนไซต์ของคุณจริง ๆ ควรเป็นคำขอ GET แม้ว่าจะเป็นฟอร์มคุณยังสามารถตั้งเป็นคำขอได้ ในขณะที่คนอื่น ๆ ชี้ให้เห็นว่าคุณสามารถแคชผลลัพธ์ของ POST ได้ แต่มันก็ไม่ได้หมายถึงความหมายเพราะ POST by definition กำลังเปลี่ยนแปลงข้อมูล


คำขอ POST อาจไม่เปลี่ยนแปลงข้อมูลใด ๆ ที่ใช้ในการสร้างหน้าการตอบกลับซึ่งในกรณีนี้อาจเหมาะสมที่จะแคชการตอบสนอง
David Z

David Z: แน่นอนถ้า POST กำลังเปลี่ยนแปลงข้อมูลดังนั้นการตอบสนองควรเป็นตัวบ่งชี้ถึงความสำเร็จ / ความล้มเหลว ไม่ต้องการแน่นอน แต่ฉันไม่สามารถนึกถึงสถานการณ์ที่ POST จะเปลี่ยนข้อมูลและการตอบสนองจะคงที่
Morvael

6
หากข้อมูลพารามิเตอร์ยาวเกินไปคำขอ GET จะไม่ทำงานกับเซิร์ฟเวอร์ทั้งหมดดังนั้นจึงต้องมี POST โดยเฉพาะอย่างยิ่งหากแหล่งข้อมูลควรทำงานบนเซิร์ฟเวอร์ที่ผู้เขียนรหัสไม่ได้กำหนดค่า
Gogowitsch

@Gogowitsch จริงมากคุณจะพบรหัสข้อผิดพลาด 414 - stackoverflow.com/a/2891598/792238
Siddhartha

-2

ด้วย firefox 27.0 และด้วย httpfox เมื่อวันที่ 19 พฤษภาคม 2014 ฉันเห็นบรรทัดนี้: 00: 03: 58.777 0.488 657 (393) POST (แคช) ข้อความ / html https://users.jackiszhp.info/S4UP

เห็นได้ชัดว่าการตอบสนองของวิธีการโพสต์ถูกแคชและมันก็อยู่ใน https เหลือเชื่อ!


-3

POST ใช้ในสถานะอาแจ็กซ์ การส่งคืนการตอบกลับที่แคชไว้สำหรับ POST จะเอาชนะช่องทางการสื่อสารและผลข้างเคียงของการรับข้อความ นี่แย่มาก ๆ นอกจากนี้ยังเป็นความเจ็บปวดที่แท้จริงในการติดตาม ขอแนะนำอย่างยิ่งกับ

ตัวอย่างเล็ก ๆ น้อย ๆ จะเป็นข้อความที่ในฐานะที่เป็นผลข้างเคียงจ่ายเงินเดือนของคุณ $ 10,000 ต่อสัปดาห์ปัจจุบัน คุณไม่ต้องการได้รับ "ตกลงมันผ่าน!" หน้าเว็บที่ถูกแคชเมื่อสัปดาห์ที่แล้ว กรณีอื่น ๆ ในโลกแห่งความเป็นจริงที่ซับซ้อนมากขึ้นส่งผลให้เกิดความฮือฮาที่คล้ายกัน


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