Kiểm soát bộ nhớ cache là gì: riêng tư?


148

Khi tôi truy cập chesseng.herokuapp.com tôi nhận được một tiêu đề phản hồi trông giống như

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

và sau đó tôi làm mới trang và nhận

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

vì vậy có vẻ như bộ nhớ đệm đang hoạt động. Nếu điều đó hoạt động cho bộ nhớ đệm thì điểm Hết hạnKiểm soát bộ đệm : tuổi tối đa là bao nhiêu . Để thêm vào sự nhầm lẫn, khi tôi kiểm tra trang tại https://developers.google.com/speed/pagespeed/insights/, nó sẽ cho tôi biết "Tận dụng bộ nhớ đệm trình duyệt".


Câu trả lời:


74

Để trả lời câu hỏi của bạn về lý do tại sao bộ nhớ đệm hoạt động, mặc dù máy chủ web không bao gồm các tiêu đề:

  • Hết hạn [a date]
  • Kiểm soát bộ nhớ cache: max-age =[seconds]

Máy chủ vui lòng yêu cầu bất kỳ proxy trung gian nào không lưu trữ nội dung (tức là mục chỉ nên được lưu trong bộ đệm riêng , tức là chỉ trên máy cục bộ của riêng bạn):

  • Kiểm soát bộ nhớ cache: riêng tư

Nhưng máy chủ đã quên bao gồm bất kỳ gợi ý bộ đệm nào:

  • họ quên bao gồm Hết hạn , vì vậy trình duyệt biết sử dụng bản sao được lưu trong bộ nhớ cache cho đến ngày đó
  • họ đã quên bao gồm Max-Age , vì vậy trình duyệt biết mục được lưu trong bộ nhớ cache trong bao lâu
  • họ quên bao gồm E-Tag , vì vậy trình duyệt có thể thực hiện một yêu cầu có điều kiện

Nhưng họ đã bao gồm một ngày sửa đổi lần cuối trong phản hồi:

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

Bởi vì trình duyệt biết ngày tệp được sửa đổi, nó có thể thực hiện một yêu cầu có điều kiện . Nó sẽ yêu cầu máy chủ cho tệp, nhưng hướng dẫn máy chủ chỉ gửi tệp nếu nó đã được sửa đổi kể từ 2012/10/16 3:13:38:

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

Máy chủ nhận được yêu cầu, nhận ra rằng máy khách đã có phiên bản mới nhất. Thay vì gửi ứng dụng khách 200 OK, theo sau là nội dung của trang, thay vào đó, nó cho bạn biết rằng phiên bản được lưu trong bộ nhớ cache của bạn là tốt:

304 Not Modified

Trình duyệt của bạn đã phải chịu sự chậm trễ của việc gửi yêu cầu đến máy chủ và chờ phản hồi, nhưng nó đã tiết kiệm được việc phải tải lại nội dung tĩnh.

Tại sao tuổi tối đa ? Tại sao hết hạn ?

Bởi vì Last-Modified hút.

Không phải tất cả mọi thứ trên máy chủ đều có ngày liên quan đến nó. Nếu tôi đang xây dựng một trang một cách nhanh chóng, không có ngày nào liên quan đến nó - bây giờ là . Nhưng tôi hoàn toàn sẵn sàng để người dùng lưu trữ trang chủ trong 15 giây:

200 OK
Cache-Control: max-age=15

Nếu người dùng búa F5, họ sẽ tiếp tục nhận phiên bản được lưu trong bộ nhớ cache trong 15 giây. Nếu đó là proxy công ty, thì tất cả 67198 người dùng truy cập cùng một trang trong cùng một cửa sổ 15 giây sẽ nhận được cùng một nội dung - tất cả được phục vụ từ bộ đệm gần. Hiệu suất chiến thắng cho tất cả mọi người.

Ưu điểm của việc thêm vào Cache-Control: max-agelà trình duyệt thậm chí không phải thực hiện một yêu cầu có điều kiện .

  • nếu bạn chỉ định Last-Modified, trình duyệt phải thực hiện yêu cầu If-Modified-Sincevà xem 304 Not Modifiedphản hồi
  • nếu bạn đã chỉ định max-age, trình duyệt thậm chí sẽ không phải chịu sự cố trên mạng; nội dung sẽ ra khỏi bộ nhớ cache

Sự khác biệt giữa "Kiểm soát bộ đệm: tuổi tối đa" và "Hết hạn"

Expireslà một di sản tương đương với tiêu đề hiện đại (c. 1998) Cache-Control: max-age:

  • Expires: bạn chỉ định một ngày (yuck)
  • max-age: bạn chỉ định giây (lòng tốt)
  • Và nếu cả hai được chỉ định, thì trình duyệt sẽ sử dụng max-age:

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

Bất kỳ trang web nào được viết sau năm 1998 không nên sử dụng Expiresnữa mà thay vào đó hãy sử dụng max-age.

ETag là gì?

ETag tương tự như Sửa đổi lần cuối , ngoại trừ việc nó không phải là một ngày - nó chỉ phải là một cái gì đó .

Nếu tôi lấy danh sách các sản phẩm ra khỏi cơ sở dữ liệu, máy chủ có thể gửi lần cuối rowversiondưới dạng ETag, thay vì ngày:

200 OK
ETag: "247986"

ETag của tôi có thể là hàm băm SHA1 của tài nguyên tĩnh (ví dụ: hình ảnh, js, css, phông chữ) hoặc của trang được kết xuất được lưu trong bộ nhớ cache (nghĩa là đây là wiki MDN của Mozilla làm; họ băm đánh dấu cuối cùng):

200 OK
ETag: "33a64df551425fcc55e4d42a148795d9f25f89d4"

Và chính xác như trong trường hợp yêu cầu có điều kiện dựa trên Sửa đổi lần cuối :

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

304 Not Modified

Tôi có thể thực hiện một yêu cầu có điều kiện dựa trên ETag:

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

304 Not Modified

An ETagvượt trội hơn Last-Modifiedbởi vì nó hoạt động cho những thứ bên cạnh các tập tin , hoặc những thứ có khái niệm về ngày . Nó chỉ


1
Tuyệt vời! Tôi đặt một tiền thưởng cho câu trả lời này. Điều gì xảy ra nếu cache-controlkhông tồn tại? Và bạn chỉ có Etag? Không phải nó vẫn cần phải thực hiện một 'yêu cầu có điều kiện' đối với máy chủ sao? Hành vi tôi thấy khi tôi ngoại tuyến là nó chỉ trả về từ bộ đệm. Nhưng khi ngoại tuyến, nó không thể thực hiện yêu cầu có điều kiện đó. Vì vậy, điều đó có nghĩa là nếu nó sẽ lưu trữ vô thời hạn nếu bạn ở chế độ ngoại tuyến? Tôi đã hỏi chi tiết câu hỏi này ở đây . Bạn có thể xem một lần một lần được không?
Mật ong

167
Cache-Control: private

Cho biết rằng tất cả hoặc một phần của thông báo phản hồi được dành cho một người dùng và KHÔNG được lưu vào bộ đệm ẩn, như máy chủ proxy.

Từ RFC2616 phần 14.9.1


14
Bởi vì nó được lưu trữ bởi trình duyệt của bạn. Bạn là người dùng duy nhất mà phản hồi được dành cho.
Dan D.

13
Không, không phải vì Cache-Control:privatechỉ có các trạng thái lưu trữ chung (như bộ đệm proxy) không nên lưu trữ phản hồi.
Dan D.

5
@Trejkaz Không, nó thực sự có nghĩa là một người dùng duy nhất. Người dùng là một tài khoản có thư mục chính của riêng mình trong đó bộ đệm nằm trong đó. Những hồ sơ được sở hữu bởi cùng một người dùng có thể chia sẻ bộ đệm của họ. Như bạn đã tìm thấy. Nhưng hai cấu hình trên cùng một máy tính nếu thuộc sở hữu của những người dùng khác nhau không được chia sẻ bộ đệm của họ, trừ khi bộ đệm đó được coi là bộ đệm chung.
Dan D.

2
À, vậy là mỗi người dùng ở cấp độ hệ điều hành. Vâng, lý do tôi tự hỏi là do rò rỉ thông tin rõ ràng giữa các cửa sổ ẩn danh của Chrome và các cửa sổ không ẩn danh, sử dụng bộ đệm để thực hiện.
Trejkaz

2
@didibus proxy-revalidateyêu cầu các proxy luôn xác nhận lại trên mỗi lần truy cập. Trường hợp như privatengăn chặn proxy từ bộ nhớ đệm.
Dan D.

20

RFC 2616, phần 14.9.1 :

Cho biết rằng tất cả hoặc một phần của thông báo phản hồi được dành cho một người dùng và KHÔNG được lưu trong bộ đệm chung ... Bộ đệm riêng (không chia sẻ) CÓ THỂ lưu bộ đệm vào phản hồi.


Trình duyệt có thể sử dụng thông tin này. Tất nhiên, "người dùng" hiện tại có thể có nhiều ý nghĩa: Người dùng hệ điều hành, người dùng trình duyệt (ví dụ: cấu hình của Chrome), v.v. Nó không được chỉ định.

Đối với tôi, một ví dụ cụ thể hơn của Cache-Control: privatelà máy chủ proxy (mà thường có nhiều người sử dụng) sẽ không cache nó. Nó có nghĩa là cho người dùng cuối, và không ai khác.


FYI, RFC làm rõ rằng điều này không cung cấp bảo mật. Đó là về việc hiển thị nội dung chính xác, không bảo mật nội dung.

Việc sử dụng từ riêng tư này chỉ kiểm soát nơi phản hồi có thể được lưu trong bộ nhớ cache và không thể đảm bảo quyền riêng tư của nội dung thư.


5
Bộ đệm riêng (không chia sẻ) CÓ THỂ lưu bộ đệm phản hồi. Phần này là chính. Cảm ơn.
Oliver

0

Trường tiêu đề thực thể hết hạn sẽ đưa ra ngày / thời gian mà sau đó phản hồi được coi là cũ. Điều khiển bộ đệm: trường tối đa cho giá trị tuổi (tính bằng giây) lớn hơn so với phản hồi được coi là cũ.

Mặc dù trường tiêu đề ở trên cung cấp một cơ chế cho khách hàng để quyết định có gửi yêu cầu đến máy chủ hay không. Trong một số điều kiện, khách hàng gửi yêu cầu đến sever và giá trị tuổi của phản hồi lớn hơn giá trị tối đa, liều lượng có nghĩa là máy chủ cần gửi tài nguyên cho khách hàng? Có lẽ tài nguyên không bao giờ thay đổi.

Để giải quyết vấn đề này, HTTP1.1 cung cấp đầu được sửa đổi lần cuối. Máy chủ đưa ra ngày sửa đổi cuối cùng của phản hồi cho khách hàng. Khi máy khách cần tài nguyên này, nó sẽ gửi trường đầu If-Modified-Because đến máy chủ. Nếu ngày này trước ngày sửa đổi, máy chủ sẽ gửi tài nguyên cho khách hàng và cung cấp 200 mã. Ngược lại, nó sẽ trả về mã 304 cho khách hàng và điều này có nghĩa là khách hàng có thể sử dụng tài nguyên được lưu trong bộ nhớ cache.

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.