Cache-Control คืออะไร: ส่วนตัว?


148

เมื่อฉันเยี่ยมชมchesseng.herokuapp.comฉันได้รับส่วนหัวการตอบสนองที่ดูเหมือน

Cache-Control:private
Connection:keep-alive
Content-Encoding:gzip
Content-Type:text/css
Date:Tue, 16 Oct 2012 06:37:53 GMT
Last-Modified:Tue, 16 Oct 2012 03:13:38 GMT
Status:200 OK
transfer-encoding:chunked
Vary:Accept-Encoding
X-Rack-Cache:miss

แล้วฉันจะรีเฟรชหน้าและรับ

Cache-Control:private
Connection:keep-alive
Date:Tue, 16 Oct 2012 06:20:49 GMT
Status:304 Not Modified
X-Rack-Cache:miss

ดังนั้นดูเหมือนว่าแคชจะทำงาน ถ้าที่ทำงานสำหรับแคชแล้วสิ่งที่เป็นจุดของหมดอายุและCache-Control: max-age หากต้องการเพิ่มความสับสนเมื่อฉันทดสอบหน้าเว็บที่https://developers.google.com/speed/pagespeed/insights/มันจะบอกฉันถึง


ตรวจสอบไดอะแกรมนี้stackoverflow.com/a/49925190/3748498
pravdomil

คำตอบ:


74

หากต้องการตอบคำถามของคุณเกี่ยวกับสาเหตุที่แคชทำงานแม้ว่าเว็บเซิร์ฟเวอร์จะไม่รวมส่วนหัว:

  • หมดอายุ: [a date]
  • การควบคุมแคช: max-age =[seconds]

เซิร์ฟเวอร์กรุณาขอให้ผู้รับมอบอำนาจกลางรายใดไม่แคชเนื้อหา (เช่นควรเก็บรายการไว้ในแคชส่วนตัวเท่านั้นเช่นในเครื่องของคุณเท่านั้น):

  • การควบคุมแคช: ส่วนตัว

แต่เซิร์ฟเวอร์ลืมที่จะรวมคำแนะนำแคชใด ๆ :

  • พวกเขาลืมที่จะรวมหมดอายุดังนั้นเบราว์เซอร์รู้ว่าจะใช้สำเนาแคชจนถึงวันที่
  • พวกเขาลืมที่จะรวมMax-Ageดังนั้นเบราว์เซอร์จึงรู้ว่ารายการแคชนั้นนานแค่ไหน
  • พวกเขาลืมที่จะรวมE-Tagดังนั้นเบราว์เซอร์สามารถดำเนินการตามเงื่อนไข

แต่พวกเขารวมถึง วันที่แก้ไขครั้งสุดท้ายในการตอบสนอง:

Last-Modified: Tue, 16 Oct 2012 03:13:38 GMT

เนื่องจากเบราว์เซอร์รู้วันที่ที่ไฟล์ถูกแก้ไขจึงสามารถดำเนินการตามเงื่อนไขได้ มันจะถามเซิร์ฟเวอร์สำหรับไฟล์ แต่สั่งให้เซิร์ฟเวอร์ส่งไฟล์เท่านั้นหากไฟล์นั้นถูกแก้ไขตั้งแต่ 2012/10/16 3:13:38:

GET / HTTP/1.1
If-Modified-Since: Tue, 16 Oct 2012 03:13:38 GMT

เซิร์ฟเวอร์ได้รับคำขอตระหนักว่าลูกค้ามีเวอร์ชันล่าสุดอยู่แล้ว แทนที่จะส่งลูกค้า200 OKตามด้วยเนื้อหาของหน้าเว็บแทนมันจะบอกคุณว่าเวอร์ชันแคชของคุณดี:

304 Not Modified

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

ทำไมMax-อายุ ? ทำไมถึงตาย ?

เนื่องจากLast-Modified sucks

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

200 OK
Cache-Control: max-age=15

หากผู้ใช้ค้อนF5พวกเขาจะได้รับรุ่นแคชเป็นเวลา 15 วินาที หากเป็นพร็อกซีขององค์กรผู้ใช้ 67198 คนที่กดปุ่มหน้าเดียวกันในหน้าต่าง 15 วินาทีเดียวกันทั้งหมดจะได้รับเนื้อหาเดียวกัน - ทั้งหมดทำหน้าที่จากแคชที่ปิด ผลงานที่ชนะสำหรับทุกคน

ข้อดีของการเพิ่มCache-Control: max-ageคือเบราว์เซอร์ไม่จำเป็นต้องดำเนินการตามเงื่อนไข

  • หากคุณระบุเท่านั้นLast-Modifiedเบราว์เซอร์จะต้องดำเนินการตามคำขอIf-Modified-Sinceและคอยดู304 Not Modifiedคำตอบ
  • หากคุณระบุmax-ageเบราว์เซอร์จะไม่ต้องประสบกับเครือข่ายไปกลับ เนื้อหาจะออกมาจากแคช

ความแตกต่างระหว่าง "การควบคุมแคช: อายุสูงสุด" และ "หมดอายุ"

Expiresเป็นสิ่งที่เทียบเท่ามรดกของCache-Control: max-ageส่วนหัวที่ทันสมัย ​​(c. 1998) :

  • Expires: คุณระบุวันที่(yuck)
  • max-age: คุณระบุวินาที(ดี)
  • และหากระบุทั้งสองเบราว์เซอร์จะใช้max-age:

    200 OK
    Cache-Control: max-age=60
    Expires: 20180403T192837 
    

เว็บไซต์ใด ๆ ที่เขียนขึ้นหลังจากที่ 1998 ไม่ควรใช้อีกต่อไปและใช้แทนExpiresmax-age

ETag คืออะไร

ETagมีความคล้ายคลึงกับLast-Modifiedยกเว้นว่ามันไม่จำเป็นต้องเป็นวันที่ - มันก็จะต้องมีบางสิ่งบางอย่าง

หากฉันดึงรายการผลิตภัณฑ์ออกจากฐานข้อมูลเซิร์ฟเวอร์สามารถส่งรายการสุดท้ายrowversionเป็น ETag แทนที่จะเป็นวันที่:

200 OK
ETag: "247986"

ETag ของฉันสามารถแฮช SHA1 ของทรัพยากรแบบคงที่ (เช่นรูปภาพ, js, css, แบบอักษร) หรือของหน้าที่แสดงผลแคช (เช่นนี่คือสิ่งที่ Mozilla MDN wiki ทำ; พวกเขาแฮชอัปมาร์กอัปสุดท้าย):

200 OK
ETag: "33a64df551425fcc55e4d42a148795d9f25f89d4"

และเหมือนกับในกรณีของคำขอตามเงื่อนไขโดยยึดตามการแก้ไขครั้งสุดท้าย :

GET / HTTP/1.1
If-Modified-Since: Tue, 16 Oct 2012 03:13:38 GMT

304 Not Modified

ฉันสามารถดำเนินการตามเงื่อนไขตาม ETag:

GET / HTTP/1.1
If-None-Match: "33a64df551425fcc55e4d42a148795d9f25f89d4"

304 Not Modified

ETagจะดีกว่าLast-Modifiedเพราะมันเหมาะกับสิ่งที่นอกเหนือจากไฟล์หรือสิ่งที่มีความคิดของวัน มันเป็นเพียงแค่


1
! น่ากลัว ฉันวางรางวัลสำหรับคำตอบนี้ จะเกิดอะไรขึ้นถ้าcache-controlไม่มีอยู่? และคุณมี Etag เท่านั้น ไม่จำเป็นต้องทำการร้องขอตามเงื่อนไขกับเซิร์ฟเวอร์หรือไม่ พฤติกรรมที่ฉันเห็นเมื่อฉันออฟไลน์คือมันเพิ่งกลับมาจากแคช แต่เมื่อมันออฟไลน์จะไม่สามารถทำการร้องขอตามเงื่อนไขนั้นได้ ดังนั้นหมายความว่าถ้ามันจะแคชอย่างไม่มีกำหนดถ้าคุณอยู่ออฟไลน์? ผมเคยถามคำถามนี้แล้วในรายละเอียดที่นี่ คุณช่วยดูหน่อยได้ไหม?
ฮันนี่

167
Cache-Control: private

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

จากRFC2616 ส่วน 14.9.1


14
เพราะเบราว์เซอร์ของคุณถูกแคช คุณเป็นผู้ใช้คนเดียวที่มีไว้สำหรับการตอบสนอง
Dan D.

13
ไม่ไม่ใช่เพราะCache-Control:privateระบุว่าแคชที่ใช้ร่วมกัน (เช่นแคชพร็อกซี) ไม่ควรแคชการตอบสนอง
Dan D.

5
@Trejkaz ไม่จริงๆมันหมายถึงผู้ใช้คนเดียว ผู้ใช้คือบัญชีที่มีโฮมไดเร็กตอรี่ของตัวเองซึ่งแคชนั้นอยู่ โปรไฟล์เหล่านั้นที่เป็นเจ้าของโดยผู้ใช้เดียวกันอาจแชร์แคชของพวกเขา ตามที่คุณได้พบ แต่สองโปรไฟล์บนคอมพิวเตอร์เครื่องเดียวกันหากเจ้าของโดยผู้ใช้ที่แตกต่างกันจะต้องไม่แชร์แคชเว้นแต่ว่าแคชนั้นจะถือว่าเป็นแคชที่ใช้ร่วมกัน
Dan D.

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

2
@didibus proxy-revalidateต้องการให้พร็อกซีตรวจสอบสิทธิ์การเข้าถึงแต่ละครั้งเสมอ ที่privateป้องกันไม่ให้พร็อกซี่แคช
Dan D.

20

RFC 2616 ส่วนที่ 14.9.1 :

ระบุว่าข้อความตอบกลับทั้งหมดหรือบางส่วนมีไว้สำหรับผู้ใช้รายเดียวและต้องไม่ถูกแคชโดยแคชที่ใช้ร่วมกัน ... แคชส่วนตัว (ไม่แชร์) อาจแคชการตอบสนอง


เบราว์เซอร์สามารถใช้ข้อมูลนี้ แน่นอน "ผู้ใช้" ปัจจุบันอาจหมายถึงหลายสิ่ง: ผู้ใช้ระบบปฏิบัติการผู้ใช้เบราว์เซอร์ (เช่นโปรไฟล์ของ Chrome) ฯลฯ ไม่ได้ระบุไว้

สำหรับฉันตัวอย่างที่ชัดเจนกว่าCache-Control: privateคือพร็อกซีเซิร์ฟเวอร์ (ซึ่งโดยทั่วไปมีผู้ใช้จำนวนมาก) จะไม่แคช มันมีไว้สำหรับผู้ใช้และไม่มีใครอื่น


FYI, RFC ทำให้ชัดเจนว่านี่ไม่ได้ให้ความปลอดภัย มันเกี่ยวกับการแสดงเนื้อหาที่ถูกต้องไม่ใช่การรักษาความปลอดภัยของเนื้อหา

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


5
แคชส่วนตัว (ไม่แชร์) อาจตอบกลับแคช ส่วนนี้เป็นกุญแจสำคัญ ขอบคุณ
โอลิเวอร์

0

ฟิลด์ Expires เอนทิตีส่วนหัวจะให้วันที่ / เวลาหลังจากที่การตอบกลับถูกพิจารณาว่าค้างอยู่ฟิลด์ Cache-control: maxage จะให้ค่าอายุ (เป็นวินาที) ที่ใหญ่กว่าการตอบกลับที่พิจารณาว่าค้าง

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

เพื่อแก้ไขปัญหานี้ HTTP1.1 จะให้ส่วนหัวที่แก้ไขล่าสุด เซิร์ฟเวอร์ให้วันที่แก้ไขล่าสุดของการตอบกลับไปยังไคลเอ็นต์ เมื่อไคลเอนต์ต้องการทรัพยากรนี้มันจะส่งฟิลด์ If-Modified-Since ไปยังเซิร์ฟเวอร์ หากวันที่นี้อยู่ก่อนวันที่แก้ไขของทรัพยากรที่เซิร์ฟเวอร์จะส่งทรัพยากรให้กับลูกค้าและให้ 200 รหัสมิฉะนั้นมันจะส่งกลับรหัส 304 ให้กับลูกค้าและสิ่งนี้หมายความว่าลูกค้าสามารถใช้ทรัพยากรมันแคช

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