Sau khi tìm kiếm rất nhiều, đọc tất cả các hướng dẫn tôi đã tìm thấy và hỏi một số câu hỏi ở đây, cuối cùng tôi đã trả lời đúng (ít nhất là tôi nghĩ) về các yêu cầu HTTP nếu không có.Việc triển khai HTTP có điều kiện của tôi có được trả lời trong PHP không?
Để làm một bản tóm tắt nhanh chóng, đây là những gì tôi làm trên mỗi trang Cacheable:
session_cache_limiter('public'); //Cache on clients and proxies
session_cache_expire(180); //3 hours
header('Content-Type: ' . $documentMimeType . '; charset=' . $charset);
header('ETag: "' . $eTag . '"'); //$eTag is a MD5 of $currentLanguage + $lastModified
if ($isXML)
header('Vary: Accept'); //$documentMimeType can be either application/xhtml+xml or text/html for XHTML (based on $_SERVER['HTTP_ACCEPT'])
header('Last-Modified: ' . $lastModified);
header('Content-Language: ' . $currentLanguage);
Ngoài ra, mỗi trang có nó là URL riêng (cho mỗi ngôn ngữ). Ví dụ: "index.php" sẽ được phân phát dưới URL "/ vi/home" bằng tiếng Anh và "/ fr/accueil" bằng tiếng Pháp.
Vấn đề lớn của tôi là trả lời "304 không được sửa đổi" thành yêu cầu HTTP nếu-không khớp và nếu được sửa đổi từ HTTP chỉ khi cần.
Các doc tốt nhất mà tôi đã tìm thấy là: http://rithiur.anthd.com/tutorials/conditionalget.php
Và đây là việc thực hiện tôi đã làm của nó (đoạn mã này được gọi là càng sớm càng tốt trên các trang có thể được lưu trữ):
$ifNoneMatch = array_key_exists('HTTP_IF_NONE_MATCH', $_SERVER) ? $_SERVER['HTTP_IF_NONE_MATCH'] : false;
$ifModifiedSince = array_key_exists('HTTP_IF_MODIFIED_SINCE', $_SERVER) ? $_SERVER['HTTP_IF_MODIFIED_SINCE'] : false;
if ($ifNoneMatch !== false && $ifModifiedSince !== false)
{
//Both if-none-match and if-modified-since were received.
//They must match the document values in order to send a HTTP 304 answer.
if ($ifNoneMatch == $eTag && $ifModifiedSince == $lastModified)
{
header('Not Modified', true, 304);
exit();
}
}
else
{
//Only one header received, it it match the document value, send a HTTP 304 answer.
if (($ifNoneMatch !== false && $ifNoneMatch == $eTag) || ($ifModifiedSince !== false && $ifModifiedSince == $lastModified))
{
header('Not Modified', true, 304);
exit();
}
}
Câu hỏi của tôi là hai lần:
- Đây có phải là cách chính xác để làm điều đó không? Ý tôi là khi nào nếu không khớp và nếu được sửa đổi được gửi, cả hai phải khớp với câu trả lời 304 và nếu chỉ một trong hai được gửi, chỉ khớp với số này là OK để gửi 304?
- Khi được sử dụng trong ngữ cảnh được mô tả ở đây, có phải 2 đoạn trích này là bộ nhớ cache công cộng thân thiện (tôi có nghĩa là bộ nhớ cache thân thiện trên proxy và Trình duyệt web)?
BTW, tôi chỉ sử dụng PHP 5.1.0+ (Tôi không hỗ trợ các phiên bản thấp hơn điều đó).
Chỉnh sửa: Đã thêm tiền thưởng ... Tôi mong đợi câu trả lời chất lượng. Đừng trả lời/bỏ phiếu nếu bạn đang đoán gì đó!
Lưu ý rằng phần thông số RFC2616 (HTTP1.1) 14.26 nói về cú pháp của If-None-Match. Cả câu hỏi này lẫn câu hỏi gốc đều không được phép cho nhiều giá trị etag hoặc "*". Điều đó đang được nói, giả định này có lẽ là đúng 99,9% thời gian. – MZB
@Mike Bell: Vâng, tôi biết rằng ETag có thể chứa nhiều giá trị hoặc * nhưng tôi không biết bất kỳ trình duyệt nào đang sử dụng tính năng này ... Tôi tự hỏi liệu có hệ thống nào thực sự sử dụng điều này không. BTW làm thế nào để phân tích ETag khi có nhiều hơn 1 giá trị trong đó? * Có nghĩa là gì trong ETag? – AlexV
@ St.Woland: Tôi đã đọc bài viết được cung cấp và xem biểu đồ của bạn (công việc tuyệt vời) và dường như nó tương ứng với phần "khác" của tôi trong đoạn thứ 2 của tôi (tôi có đúng không?). Những gì tôi thấy kỳ lạ với điều này là khi cả hai nếu không-không-phù hợp và nếu-sửa đổi-kể từ khi nhận được chỉ 1 trong 2 phải phù hợp để trả lời với 304 ... Là thậm chí có thể nhận được nếu không có trận đấu VÀ nếu -modified-since cùng một lúc? – AlexV