Tại sao Apache gửi 200 OK trong khi phù hợp với lần sửa đổi cuối cùng Nếu được sửa đổi-kể từ đó?


10

Tôi đang cố gắng có một hành vi cơ bản liên quan đến chiến lược lưu trữ của mình: các tệp nên được lưu trong bộ nhớ cache và được xác nhận lại với máy chủ mỗi lần. Vì vậy, tôi muốn Apache gửi lại 304.

Đây là hộp thoại xảy ra cho mỗi lần làm mới trình duyệt:

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

(đây là từ chrome devtools, với Vô hiệu hóa bộ đệm ẩn không được chọn)

Bạn có thể thấy rằng phản hồi chứa Tiêu đề kiểm soát bộ đệm: Không có bộ đệm và tiêu đề If-đã sửa đổi phù hợp với tiêu chuẩn được sửa đổi lần cuối. Các trận đấu ETag cũng vậy.

Không nên Apache gửi 304 trong trường hợp đó?

BIÊN TẬP

Vô hiệu hóa ETags trong apache với

 Header  unset ETag

làm cho hành vi bộ nhớ đệm dễ dự đoán hơn ...


Tôi nghĩ đã Cache-Control:max-age=0vô hiệu hóa bộ đệm, vì vậy bạn thấy Cache-Control:No-cachephản hồi.
ThoriumBR

Tôi rõ ràng đặt Kiểm soát bộ đệm: Không có bộ đệm trong cấu hình apache của tôi vì từ w3.org/Prot Protocol / rfc2616 / rfc2616-sec14.html # sec14.9.1 , tôi hiểu rằng nó gây ra xác nhận lại cho mỗi yêu cầu. Có xác nhận lại ngụ ý gửi lại tập tin? Tôi sẽ nói rằng nó nên sử dụng If-sửa đổi-từ để xác định xem đó là 200 hay 304.
zrz

Câu trả lời:


8

Đây dường như là một lỗi cũ , giải thích tại sao Header unset ETagtạo ra sự khác biệt.

Apache 2.4.0+ tự động thêm tên phương thức nén vào ETag (như được thấy trong các tiêu đề của bạn) và ngăn phản hồi 304.

Các phiên bản mới nhất của mod_deflate hỗ trợ DeflateAlterETag có thể được sử dụng để kiểm soát hành vi này:

DeflateAlterETag NoChange

3
Điều này đúng nhưng Apache 2.4 không chứa tùy chọn đó, chỉ có Apache 2.5. Tuy nhiên, cá nhân tôi không thấy ETags hữu ích vì Apache dựa trên ngày sửa đổi cuối cùng, thay vì nội dung tệp. Vì vậy, tắt ETags rơi trở lại tiêu đề If-Modified-Because, dựa trên ngày sửa đổi cuối cùng. Bạn có thể thay đổi ETag trong Apache để làm cho nó dựa trên kích thước, được sửa đổi lần cuối và / hoặc inode - với kích thước và lần sửa đổi cuối cùng là mặc định - nhưng, cho đến khi chúng thêm một tùy chọn để tính toán một ETag dựa trên tổng kiểm tra nội dung tệp, IMHO sử dụng hạn chế. Vì vậy, tôi tắt chúng.
Barry Pollard

1
@BazzaDP Điều đó có ý nghĩa. 2.5 cũng có một DeflateAlterETag Removetùy chọn để làm điều đó
Mathias R. Jessen

0

Điều này nổi bật trong yêu cầu là một chút kỳ lạ:

Cache-Control:max-age=0

Có khả năng quan trọng hơn, tôi nhận thấy rằng nội dung được trả về là html. Là nó đang được tạo ra năng động? Apache CÓ THỂ gửi phản hồi 304, nhưng trừ khi bạn đang phục vụ nội dung tĩnh, đó không phải là công việc của Apache để thực hiện cuộc gọi đó và nó thuộc về logic ứng dụng của bạn. Ví dụ, hầu hết các ứng dụng php có hỗ trợ hạn chế cho những thứ đó.

Bộ đệm phía trước có thể giúp ích, vì ứng dụng bộ đệm có thể kiểm tra thời gian sửa đổi, etag, v.v., nhưng chỉ khi cả ứng dụng và tiêu đề yêu cầu đều thân thiện với bộ đệm. Ví dụ: ứng dụng phải đặt các tiêu đề thích hợp để cho biết nội dung có thể lưu trong bộ nhớ cache và những thứ như tiêu đề Kiểm soát bộ đệm trong yêu cầu của bạn sẽ phủ nhận bộ đệm. Tiêu đề của bạn không tìm kiếm bộ nhớ cache thân thiện.


Tệp được yêu cầu là một tệp html tĩnh, do đó Apache có thời gian sửa đổi đúng. (Sửa đổi lần cuối: Thứ ba, ngày 14 tháng 10 năm 2014 15:10:37 GMT). tiêu đề max-age = 0 nằm trong yêu cầu được gửi bởi chrome khi tôi nhập URL và nhấn Enter. Có phải vì những phản ứng trước đó?
zrz

Tôi đọc rằng Chrome tự động thêm Kiểm soát bộ đệm: max-age = 0 vào yêu cầu (ngoại trừ lần đầu tiên bạn tải Chrome, nhập URL, nhấn enter). Nhưng điều đó dường như không ảnh hưởng đến các máy chủ khác (CDN gửi 304 ngay cả với tuổi tối đa = 0 trong yêu cầu).
zrz

@zrz: hạn chế bộ nhớ đệm trung gian rất hữu ích khi gỡ lỗi, nhưng nếu không sẽ gây hại cho hiệu suất. Kiểm tra bối cảnh của những gì bạn đọc trên chrome làm gì. Xét về những gì apache làm, nó khá cấu hình. Kiểm soát bộ đệm là một hướng dẫn cho bộ đệm trung gian, không phải cho máy chủ gốc. Tuy nhiên, apache có thể hoạt động như một bộ đệm trung gian và có thể được cấu hình để làm tất cả mọi thứ. Tôi nghĩ rằng nếu bạn đưa ra các hướng dẫn chống bộ nhớ cache, bạn sẽ có hành vi giống như những gì bạn mong đợi ở máy chủ gốc.
mc0e

0

Nếu bạn đã cấu hình Apache Cache-Control:No-cache, Apache sẽ không bao giờ gửi HTTP 304 Not modifiedcho khách hàng.

Nếu bạn muốn xác nhận lại một số yêu cầu, chỉ đặt một Cache-Control:No-cachesố trang mà bạn cần. Bạn không cần xác nhận lại tất cả các tài nguyên và bạn đang lãng phí băng thông bằng cách làm như vậy.


Tôi dường như bị nhầm lẫn bởi thuật ngữ "xác nhận lại". Đối với tôi, nó có nghĩa là kiểm tra xem nó có phải là 304. Tôi có sai không?
zrz

Bạn sai rồi. Xác nhận lại là gửi lại dữ liệu cho khách hàng và buộc anh ta đọc lại mọi thứ ngay cả khi nó đã có cùng thông tin. Về cơ bản, bạn đang vô hiệu hóa bộ đệm trên mọi máy khách.
ThoriumBR

Điều đó giải thích rất nhiều. Điều cuối cùng tôi cần giải thích là trong suy nghĩ đó là Apache gửi 304 cho một số tài nguyên (ví dụ như png), trong khi tôi vẫn có Bộ điều khiển bộ đệm không đặt No-cache trong phản hồi và tối đa = 0 trong yêu cầu. Có manh mối nào không?
zrz

@ThoriumBR Nếu tôi giải thích chính xác cho bạn, cả hai câu trả lời của bạn đều không chính xác ở đây; no-cache (trái ngược với no-store) không có nghĩa là "không cache" và có thể dẫn đến 304 nếu nội dung không thay đổi. Thật vậy, OP đã mong đợi điều này nhưng không hiểu vì vấn đề etag. phải xác nhận lại liên quan đến cách xử lý nội dung cũ và không phải lúc nào cũng gửi "dữ liệu lại".
Nick
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.