ทำไม Apache ส่ง 200 OK ในขณะที่การปรับเปลี่ยนครั้งล่าสุดตรงกับ If-modified- ตั้งแต่


10

ฉันพยายามที่จะมีพฤติกรรมพื้นฐานเกี่ยวกับกลยุทธ์การแคชของฉัน: ไฟล์ควรถูกแคชและตรวจสอบความถูกต้องกับเซิร์ฟเวอร์ใหม่ทุกครั้ง ดังนั้นฉันอยากให้ Apache ส่ง 304 กลับมา

นี่คือกล่องโต้ตอบที่เกิดขึ้นสำหรับการรีเฟรชเบราว์เซอร์แต่ละครั้ง:

Status Code:200 OK

Request Headers

Accept:text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8
Accept-Encoding:gzip,deflate,sdch
Accept-Language:fr-FR,fr;q=0.8,en-US;q=0.6,en;q=0.4
Cache-Control:max-age=0
Connection:keep-alive
Cookie: ...
Host:...
If-Modified-Since:Tue, 14 Oct 2014 15:10:37 GMT
If-None-Match:"1461-505636af08fcd-gzip"
User-Agent:Mozilla/5.0 (X11; Linux i686) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/34.0.1847.116 Safari/537.36

Response Headers

Accept-Ranges:bytes
Cache-Control:No-cache
Connection:Keep-Alive
Content-Encoding:gzip
Content-Length:1412
Content-Type:text/html
Date:Tue, 14 Oct 2014 16:58:05 GMT
ETag:"1461-505636af08fcd-gzip"
Keep-Alive:timeout=5, max=99
Last-Modified:Tue, 14 Oct 2014 15:10:37 GMT
Server:Apache/2.4.6 (Ubuntu)
Vary:Accept-Encoding

(นี่คือจาก Chrome devtools โดยไม่ได้เลือกที่จะไม่ใช้แคช)

คุณสามารถเห็นว่าการตอบสนองประกอบด้วย Cache-Control: No-cache Header และหัวข้อ If-modified-ตั้งแต่ตรงกับ Last-modified ETag ก็ตรงกันเช่นกัน

Apache ไม่ควรส่ง 304 ในกรณีนี้หรือ

แก้ไข

ปิดใช้งาน ETags ใน apache ด้วย

 Header  unset ETag

ทำให้พฤติกรรมแคชคาดการณ์ได้มากขึ้น ...


ฉันคิดว่าCache-Control:max-age=0ปิดการใช้งานแคชดังนั้นคุณจะเห็นการCache-Control:No-cacheตอบสนอง
ThoriumBR

ฉันตั้งค่า Cache-Control อย่างชัดเจน: ไม่แคชในการกำหนดค่า apache ของฉันเพราะจากw3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.9.1ฉันเข้าใจว่ามันทำให้เกิดการตรวจสอบซ้ำสำหรับแต่ละคำขอ การตรวจสอบซ้ำหมายถึงการส่งไฟล์อีกครั้งหรือไม่ ผมจะบอกว่ามันควรจะใช้ถ้าปรับเปลี่ยนตั้งแต่การตรวจสอบว่ามันเป็น 200 หรือ 304
zrz

คำตอบ:


8

นี่ดูเหมือนจะเป็นบั๊กเก่าอธิบายว่าทำไมHeader unset ETagสร้างความแตกต่าง

Apache 2.4.0+ จะผนวกชื่อวิธีการบีบอัดให้กับ ETag โดยอัตโนมัติ (ดังที่เห็นในส่วนหัวของคุณ) และป้องกันการตอบสนอง 304

Mod_deflateรุ่นใหม่ล่าสุดรองรับDeflateAlterETagที่สามารถใช้ควบคุมพฤติกรรมนี้:

DeflateAlterETag NoChange

3
สิ่งนี้ถูกต้อง แต่ Apache 2.4 ไม่มีตัวเลือกนั้นเพียง Apache 2.5 อย่างไรก็ตามโดยส่วนตัวฉันไม่พบ ETags ที่มีประโยชน์เนื่องจาก Apache ใช้ฐานกับวันที่แก้ไขล่าสุดแทนที่จะเป็นเนื้อหาไฟล์ ดังนั้นการปิด ETags จะกลับไปที่ส่วนหัว If-Modified-Since ซึ่งจะอ้างอิงตามวันที่แก้ไขล่าสุด คุณสามารถแก้ไข ETag ใน Apache เพื่อให้เป็นไปตามขนาด, แก้ไขล่าสุดและ / หรือ inode - ด้วยขนาดและแก้ไขล่าสุดเป็นค่าเริ่มต้น - แต่จนกว่าพวกเขาจะเพิ่มตัวเลือกในการคำนวณ ETag ตามการตรวจสอบเนื้อหาไฟล์ IMHO จำกัด การใช้งาน ดังนั้นฉันจะปิดพวกเขา
Barry Pollard

1
@BazzaDP นั่นสมเหตุสมผลแล้ว 2.5 นอกจากนี้ยังมีDeflateAlterETag Removeตัวเลือกให้ทำเช่นนั้น
Mathias R. Jessen

0

อันนี้มีความโดดเด่นในคำขอเป็นบิตแปลก:

Cache-Control:max-age=0

มีความสำคัญมากกว่า แต่ฉันสังเกตว่าเนื้อหาที่ส่งคืนเป็น html มันถูกสร้างแบบไดนามิกหรือไม่? Apache MAY ส่งการตอบกลับ 304 แต่ถ้าคุณไม่ได้ให้บริการเนื้อหาแบบคงที่ไม่ใช่งานของ Apache ที่จะทำการโทรออก เช่นแอปพลิเคชัน php ส่วนใหญ่ได้รับการสนับสนุนอย่าง จำกัด สำหรับสิ่งต่างๆ

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


ไฟล์ที่ร้องขอเป็นไฟล์ html แบบคงที่ซึ่ง Apache จะได้รับเวลาในการแก้ไขที่ถูกต้อง (แก้ไขครั้งล่าสุด: อังคาร, 14 ต.ค. 2014 15:10:37 GMT) max-age = 0 header อยู่ในคำขอที่ส่งโดย chrome เมื่อฉันพิมพ์ URL และกด Enter มีเพราะคำตอบก่อนหน้า?
zrz

ฉันอ่านว่า Chrome เพิ่มการควบคุมแคชโดยอัตโนมัติ: max-age = 0 เพื่อขอ (ยกเว้นครั้งแรกที่คุณโหลด Chrome ให้พิมพ์ URL กด Enter) แต่ดูเหมือนจะไม่ส่งผลกระทบต่อเซิร์ฟเวอร์อื่น ๆ (CDNs ส่ง 304 แม้จะมี max-age = 0 ในคำขอ)
zrz

@zrz: การ จำกัด การแคชตัวกลางมีประโยชน์มากเมื่อทำการดีบั๊ก แต่อาจเป็นอันตรายต่อประสิทธิภาพการทำงาน ตรวจสอบบริบทของสิ่งที่คุณอ่านเกี่ยวกับสิ่งที่โครเมี่ยมทำ ในแง่ของสิ่งที่ Apache ทำมันค่อนข้างกำหนดค่าได้ การควบคุมแคชเป็นคำสั่งสำหรับแคชตัวกลางไม่ใช่สำหรับเซิร์ฟเวอร์ต้นทาง อย่างไรก็ตาม apache สามารถทำหน้าที่เป็นแคชตัวกลางและสามารถกำหนดค่าให้ทำสิ่งต่าง ๆ ได้ทุกประเภท ฉันคิดว่าถ้าคุณทำตามคำแนะนำในการต่อต้านการแคชคุณจะได้รับพฤติกรรมมากกว่าที่คุณคาดหวังจากเซิร์ฟเวอร์ต้นทาง
mc0e

0

หากคุณมีการกำหนดค่า Apache ด้วยCache-Control:No-cacheApache จะไม่ส่งHTTP 304 Not modifiedไปยังลูกค้า

หากคุณต้องการตรวจสอบความถูกต้องอีกครั้งให้ใส่Cache-Control:No-cacheเฉพาะหน้าที่คุณต้องการเท่านั้น คุณไม่จำเป็นต้องตรวจสอบความถูกต้องของทรัพยากรทั้งหมดอีกครั้งและคุณกำลังเสียแบนด์วิดท์ด้วยการทำเช่นนั้น


ฉันดูเหมือนจะสับสนกับคำว่า "ตรวจสอบใหม่" สำหรับฉันมันหมายถึงการตรวจสอบว่ามันเป็น 304 ฉันผิดหรือเปล่า?
zrz

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

นั่นอธิบายได้มาก สิ่งสุดท้ายที่ฉันต้องอธิบายว่าในใจคือ Apache ส่ง 304 สำหรับทรัพยากรบางอย่าง (เช่น png) ในขณะที่ฉันยังมี Cache-Control นั้นตั้งค่า No-cache ในการตอบกลับและ max-age = 0 ในคำขอ เบาะแสใด ๆ
zrz

@ThoriumBR หากฉันตีความคุณถูกต้องคำตอบทั้งคู่ของคุณไม่ถูกต้องที่นี่ ไม่แคช (ตรงข้ามกับที่ไม่มีร้านค้า) ไม่ได้หมายความว่า "ไม่แคช" และอาจส่งผลให้ 304 หากเนื้อหาไม่เปลี่ยนแปลง อันที่จริงผู้ปฏิบัติการคาดหวังสิ่งนี้ แต่ไม่ได้รับเนื่องจากปัญหา etag ต้องตรวจสอบใหม่เกี่ยวข้องกับวิธีการจัดการเนื้อหาเก่าและไม่ส่ง "ข้อมูลทั้งหมดอีกครั้ง"
Nick
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.