什么 304 Not Modified Header
客户端(一般是浏览器)发送了一个带条件的 GET 请求且该请求已被允许,而文档的内容(自上次访问以来或者根据请求的条件)并没有改变,则服务器应当返回 304 Not Modified 这个状态码。
浏览器在请求一个文件的时候,发现自己缓存的文件有 Last Modified ,那么在请求中会包含 If Modified Since ,这个时间就是缓存文件的 Last Modified 。因此,如果请求中包含 If Modified Since,就说明已经有缓存在客户端,只要判断这个时间和当前请求的文件的修改时间就可以确定是返回 304 还是 200。
WordPress 中如何开启 304 Not Modified Header
WordPress 作为一个 CMS 系统,如果每天更新的内容不多,对于未登录的用户来说,每次访问同一个页面,如果浏览器中已经有缓存,其实服务器无需再次生成一次页面,直接返回 304 Not Modified Header,让用户直接查看浏览器中缓存即可。
那么在 WordPress 中如何给未登录用户开启 304 Not Modified Header 呢?可以在当前主题的 functions.php
函数加入以下代码:
add_filter('wp_headers','wpjam_headers',10,2);
function wpjam_headers($headers,$wp){
if(!is_user_logged_in() && empty($wp->query_vars['feed'])){
$headers['Cache-Control'] = 'max-age:600';
$headers['Expires'] = gmdate('D, d M Y H:i:s', time() 600) . " GMT";
$wpjam_timestamp = get_lastpostmodified('GMT')>get_lastcommentmodified('GMT')?get_lastpostmodified('GMT'):get_lastcommentmodified('GMT');
$wp_last_modified = mysql2date('D, d M Y H:i:s', $wpjam_timestamp, 0).' GMT';
$wp_etag = '"' . md5($wp_last_modified) . '"';
$headers['Last-Modified'] = $wp_last_modified;
$headers['ETag'] = $wp_etag;
// Support for Conditional GET
if (isset($_SERVER['HTTP_IF_NONE_MATCH']))
$client_etag = stripslashes(stripslashes($_SERVER['HTTP_IF_NONE_MATCH']));
else $client_etag = false;
$client_last_modified = empty($_SERVER['HTTP_IF_MODIFIED_SINCE']) ? '' : trim($_SERVER['HTTP_IF_MODIFIED_SINCE']);
// If string is empty, return 0. If not, attempt to parse into a timestamp
$client_modified_timestamp = $client_last_modified ? strtotime($client_last_modified) : 0;
// Make a timestamp for our most recent modification...
$wp_modified_timestamp = strtotime($wp_last_modified);
$exit_required = false;
if ( ($client_last_modified && $client_etag) ?
(($client_modified_timestamp >= $wp_modified_timestamp) && ($client_etag == $wp_etag)) :
(($client_modified_timestamp >= $wp_modified_timestamp) || ($client_etag == $wp_etag)) ) {
$status = 304;
$exit_required = true;
}
if ( $exit_required ){
if ( ! empty( $status ) ){
status_header( $status );
}
foreach( (array) $headers as $name => $field_value ){
@header("{$name}: {$field_value}");
}
if ( isset( $headers['Last-Modified'] ) && empty( $headers['Last-Modified'] ) && function_exists( 'header_remove' ) ){
@header_remove( 'Last-Modified' );
}
exit();
}
}
return $headers;
}
该功能已经整合到 WPJAM Basic 插件中,现已免费提供下载,你只需要勾选下就可以自动添加!
上图就是我爱水煮鱼针对未登录用户开启 304 缓存之后,用户再次访问同一页面时候得到 304 Not Modified 状态。
开启 304 状态,相应会带来一些问题,比如用户更新留言了,其他用户可能会看不到,当然如果你要你用第三方评论系统,那就不存在这个问题,还有 Postview 会有一些统计不再计入等各种问题,你可以根据自己的需求开启。