Các tiêu đề để ngăn chặn các yêu cầu 304 / If-sửa đổi-từ / HEAD


31

Tôi nên gửi tiêu đề nào để hoàn toàn dừng tất cả các yêu cầu đến máy chủ sau khi nội dung được lưu trữ?

Chúng tôi có một máy chủ có độ trễ rất cao (Sigh, VMWare) nên ngay cả việc gửi HEADyêu cầu đến máy chủ cũng mất + 40ms.

Hiện tại đây là các tiêu đề được gửi / nhận;

Yêu cầu đầu tiên

Khách hàng gửi;

GET http://dugong:8080/Rvi24mYJkxFRGNzq73PPvgWGh1j/IMG_2071.jpg HTTP/1.1
Host: dugong:8080
User-Agent: Mozilla/5.0 (Windows NT 5.1; rv:9.0) Gecko/20100101 Firefox/9.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: en-us,en;q=0.5
Accept-Encoding: gzip, deflate
Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.7
Pragma: no-cache, no-cache, no-cache
Cache-Control: no-cache, no-cache, no-cache

Máy chủ trả lời;

HTTP/1.1 200 OK
Server: nginx/1.0.11
Date: Wed, 01 Feb 2012 14:51:51 GMT
Content-Type: text/plain
Vary: Accept-Encoding
Last-Modified: Tue, 31 Jan 2012 10:45:11 GMT
Content-Length: 14
Expires: Thu, 31 Jan 2013 14:51:51 GMT
Cache-Control: max-age=31536000

Vì vậy, nó sẽ gửi một tiêu đề Cache-ControlExpiresđược đặt thành 365 ngày trong tương lai. Thật không may, trong lần làm mới thứ hai, nó lại yêu cầu đối tượng với một If-Modified-Sincetiêu đề.

Yêu cầu lần thứ hai

GET http://dugong:8080/Rvi24mYJkxFRGNzq73PPvgWGh1j/IMG_2071.jpg HTTP/1.1
Host: dugong:8080
User-Agent: Mozilla/5.0 (Windows NT 5.1; rv:9.0) Gecko/20100101 Firefox/9.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: en-us,en;q=0.5
Accept-Encoding: gzip, deflate
Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.7
If-Modified-Since: Tue, 31 Jan 2012 10:45:11 GMT
Cache-Control: max-age=0

Phản ứng;

HTTP/1.1 304 Not Modified
Server: nginx/1.0.11
Date: Wed, 01 Feb 2012 14:58:00 GMT
Vary: Accept-Encoding
Expires: Thu, 31 Jan 2013 14:58:00 GMT
Cache-Control: max-age=31536000

Thật không may do phần mềm proxy lỗi thời mà chúng tôi không thể sử dụng Keep-Alivehoặc đặt bất kỳ máy chủ / proxy nào khác trước ứng dụng. Chúng tôi cũng không thể cải thiện hiệu suất của máy chủ và giảm độ trễ mạng. Tôi đã cố gắng tìm ra những tiêu đề nào chúng tôi có thể gửi để loại bỏ 301 yêu cầu. Tôi đã thử sử dụng ETags nhưng điều đó không có gì khác biệt, nó vẫn gửi một If-modified-sincetiêu đề. Tôi cũng đã thử xóa Last-Modifiedtiêu đề nhưng điều đó chỉ gây ra yêu cầu GET tiêu chuẩn mà không có bộ đệm (Đã kiểm tra nhật ký, máy chủ vẫn nhận được yêu cầu).

Khách hàng là sự pha trộn của Firefox (hầu hết), IE 7, 8 và (một số) 9, Chrome và Safari nhưng hành vi này dường như xuất hiện trong tất cả các trình duyệt được thử nghiệm.

TL; DR;

Mạng khủng khiếp, tôi nên gửi tiêu đề gì để nói với khách hàng rằng đừng bao giờ gửi If-modified-sinceyêu cầu đến máy chủ để xác thực bộ đệm của họ và giữ nội dung được lưu trong bộ nhớ cache cho đến khi Expirestiêu đề được đáp ứng?

Tôi có thể thiếu một cái gì đó rõ ràng nhưng mọi thứ tôi cố gắng dường như mang lại kết quả tương tự.

Chúng tôi có một máy chủ NGINX ngồi trước máy chủ ứng dụng của chúng tôi để tôi có thể thêm / xóa bất kỳ tiêu đề nào nếu muốn. Proxy của chúng tôi không hỗ trợ Keep-Alive và họ không có cách nào cải thiện hiệu suất mạng hấp dẫn. Do thiết kế phần mềm khủng khiếp, ứng dụng web tải +100 tài nguyên trên mỗi lần tải trang (Yeah, phần mềm doanh nghiệp hút) với độ trễ ~ 40-50ms cho mỗi đối tượng.


1
Hmm, thật lạ. Gửi hết hạn và tiêu đề tuổi tối đa sẽ ngăn các yêu cầu tiếp theo của hình ảnh. Chỉnh sửa: nhân tiện, thỏa thuận với việc gửi JPG là text/plaingì?
DisgruntledGoat

1
@DisgruntledGoat Ahh, bạn đã đưa ra giả định rằng tệp .jpg thực sự là một hình ảnh chứ không phải là một tài liệu văn bản. Chào mừng bạn đến với thế giới của tôi =) (Đây thực sự là một tệp văn bản chứa 'Hello World' cho thử nghiệm của tôi, phần mềm chỉ đổi tên tất cả các tệp tuần tự IMG_xxxx.jpg bất kể loại nào. Cool huh?)
Smudge

Bạn đã sử dụng gì để đặt tiêu đề yêu cầu http?
barlop

Câu trả lời:


25

Bạn thực sự không thể kiểm soát những gì các tác nhân người dùng tiêu đề quyết định gửi cho bạn. Nếu tệp được đề cập nằm trong bộ đệm của trình duyệt và nó quyết định nó cần kiểm tra phiên bản mới thì nó sẽ. Theo bài viết này , đây là những tình huống trình duyệt sẽ yêu cầu sử dụng If-Modified-Because:

  • Mục lưu trữ không có ngày hết hạn và nội dung được truy cập lần đầu tiên trong phiên trình duyệt
  • Mục lưu trữ có ngày hết hạn nhưng nó đã hết hạn
  • Người dùng đã yêu cầu cập nhật trang bằng cách nhấp vào nút Làm mới hoặc nhấn F5

Vì vậy, nếu bạn đang tải lại trang để kiểm tra bộ nhớ đệm của mình, nó sẽ không hoạt động vì trình duyệt sẽ yêu cầu lại hình ảnh. Hãy thử nhấp vào một liên kết sau đó một liên kết khác trở lại trang đầu tiên. Nếu người dùng của bạn thường xuyên tải lại các trang thì bạn có thể cần phải suy nghĩ lại về cấu trúc trang web / ứng dụng của mình để ngăn chặn điều đó.

Một điều có thể giúp là thêm "công khai" vào tiêu đề kiểm soát bộ đệm, tức là Cache-Control: public, max-age=31536000. Gần đây tôi cũng biết rằng thời hạn sử dụng hơn một năm là không hợp lệ. Vì ngày hết hạn của bạn là chính xác một năm, có lẽ việc giảm xuống một vài ngày hoặc vài tuần sẽ đảm bảo tệp nằm trong bộ nhớ cache của trình duyệt và không bị loại bỏ.


Thật thú vị, tôi sẽ hạ hạn sử dụng xuống còn 60 ngày và thêm cờ công khai, và xem điều gì sẽ xảy ra. Điều này dường như đang xảy ra trên các nhấp chuột liên kết chứ không phải F5 (theo bản ghi của Fireorms và máy chủ)
Smudge

Về mặt kỹ thuật, thông số HTTP / 1.1 chỉ nói rằng "các máy chủ KHÔNG NÊN gửi ngày hết hạn hơn một năm trong tương lai" (có lẽ vì đó là một khoảng thời gian dài vô lý trước khi hết hạn) và "khoảng một năm" trong tương lai là hết hạn thích hợp thời gian để gửi cho nội dung không bao giờ được dự kiến ​​sẽ hết hạn.
Ilmari Karonen

1
Sau một hồi chơi, tôi đã kết luận rằng hết hạn 365 ngày không ảnh hưởng đến khách hàng của chúng tôi tuy nhiên tôi đã bỏ nó xuống để an toàn, có vẻ như đó Cache-Control: public,...là chìa khóa cho tình huống cụ thể này.
Smudge

Bạn có nghĩa là tiêu đề "công khai" đã cố định các chuyến đi khứ hồi không cần thiết? Tôi đã thử nó, nhưng không thành công ...
phtrivier

2
Trong trường hợp không rõ câu trả lời của tôi, tải lại trang trong trình duyệt của bạn sẽ yêu cầu lại các tệp . Chỉ cần nhấp vào liên kết để mở các trang và trình duyệt sử dụng bộ đệm của nó.
DisgruntledGoat


3

Tôi cũng gặp vấn đề tương tự và các Yêu cầu chắc chắn đánh vào máy chủ để nó phản hồi với 304trạng thái - Tôi đang gửi 304 qua một số C # và chắc chắn rằng nó sẽ chạm vào máy chủ ..

Tôi chỉ có Cache-Control: privatethiết lập. Không max-agevà không ExpiresNó hoạt động như mong đợi; đánh vào máy chủ với If-Modified-Sincenơi tôi kiểm tra giá trị so với những gì tôi mong đợi và cung cấp 304phần thân phản hồi trống - khác 200& đầy đủ phần thân phản hồi.

Cài đặt Expirestiêu đề có kết quả mong muốn, 200 - (from cache)trên máy khách và không có yêu cầu HTTP nào đánh vào máy chủ.

Nhưng .. Tôi thấy rằng việc đặt BÓNG max-age= & Expirescó thể khiến trình duyệt không gửi If-Modified-Sincetiêu đề VÀ hoàn toàn không lưu vào bộ đệm nếu các giá trị không khớp .

Một cái gì đó cần lưu ý nếu bạn có vấn đề về bộ nhớ đệm & sử dụng kết hợp các tiêu đề khác nhau.


1

Một chút lạc đề nhưng có thể hữu ích. Một cải tiến khác cho các yêu cầu của bạn về nội dung được lưu trong bộ nhớ cache, là lưu vào bộ đệm trong sessionStorage để bạn không cần yêu cầu máy chủ xác thực bộ đệm và nhận 304. Hãy tìm ví dụ google, mở bảng điều khiển và viết sessionStorage. Bạn sẽ thấy rằng họ đang lưu trữ CSS hoặc DOM với sessionStorage. Tất nhiên, bạn không thể sử dụng nó trong các trình duyệt IE cũ.


0

Xem qua mã nguồn của bạn và đảm bảo không có META REFRESH để chuyển sang trang khác. Sử dụng một cái gì đó như sendRedirect thay thế. Trong thiết lập của tôi, META REFRESH tạo ra 304 trong IE, nhưng không phải Chrome. sendRedirect không tạo ra cái này trên cả hai trình duyệt.

<meta http-equiv="refresh" content="0;URL='nextpage'" />    

đấu với

<% response.sendRedirect("nextpage") %>
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.