小萌博客 - 既是个人原创，又是汇聚分享 - immoe.org - 状态码
type: channel
link: https://www.immoe.org/tag/%E7%8A%B6%E6%80%81%E7%A0%81/
items: 使用HTTP缓存状态码200和304提升网站访问速度

使用HTTP缓存状态码200和304提升网站访问速度
type: item
date: 2018-04-30T17:42:00+08:00
description: 本文转载自火端网络，由小萌进行编辑网站访问速度对一个网站来说是非常重要的，访问慢会流失用户，访问快会大大的提高用户体验。提升网站访问速度的方式很多，比如这里提升PHP程序运行速度的几个优化方案，但我们今天要介绍的是HTTP缓存，也可以叫浏览器缓存。浏览器缓存大概有两种，200 OK (from memory/disk cache)和304 Not Modified他们各有各的优势，把他们发挥好可以大大的提升访问速度。200 OK (from memory/disk cache)这种缓存方式已经很普遍，大部分网站的静态文件都采用了，200 OK (from memory cache)或者200 OK (from disk cache)都是直接读取客户端的缓存，无需再请求服务器。一般是在Apache或者Nginx里设置，比如Nginx配置里会有类似这样的配置：location ~ .*\.(gif|jpg|jpeg|png|bmp|swf)$ { expires 30d; } location ~ .*\.(js|css)?$ { expires 12h; }这样就可以给静态文件缓存了，在有效期内，浏览器会直接读取客户端的缓存，而不用再请求服务器，除非用户清除了缓存或者使用Ctrl+F5强制刷新了页面。比如上图，是已经缓存过了的，至于有些是200 OK (from memory cache)有些会是200 OK (from disk cache)都差不多，只是从客户端取的位置不一样而已。除了给静态文件做200 OK (from cache)缓存外，其实我们也可以给某些页面做，比如一些不经常改变内容的ajax页面。举个例子：一个在线手册网站，左侧是导航，用户浏览手册时可能会频繁在不同的文档页面来回切换，如果不启用HTTP缓存，体验会非常差，如果使用Ajax切换，再加上200 OK (from cache)就可以做到快速切换了，无刷新、无白屏，体验棒棒哒！200缓存能大大的提升速度，但是如果网站内容有更新，访客是无法及时的获取最新的内容。这时候我们一般是采用在静态文件后面加参数来解决，比如 /statis/js/jquery.js?20180505 ，因为是一个新的URL，所以浏览器没有缓存可取，只能取新内容。304 Not Modified304缓存和上面最大的区别是浏览器需要向服务器询问一次，如果服务器端认为没有内容更新，直接返回304状态码，无需返回body内容，浏览器就会直接取缓存内容输出，这样省掉了没必要的数据传输，也就提升了访问速度。要实现304缓存，我们需要在浏览器首次访问时返回过期时间等header，比如如下PHP代码：$time=86400; //单位秒 header('Cache-Control:max-age=' . $time); header("Expires: " . gmdate("D, d M Y H:i:s", time() + $time) . " GMT"); header("Last-Modified: " . gmdate("D, d M Y H:i:s") . " GMT");上面的代码就告诉了浏览器缓存时间，下次浏览器再访问该页面的时候会带上名叫IF_MODIFIED_SINCE的请求头来访问，这时候我们可以用PHP变量：$_SERVER['HTTP_IF_MODIFIED_SINCE']来获取浏览器记录的缓存时间，如果没有内容更新，我们直接返回304状态码即可，如果有更新直接输出新内容，并返回新的过期时间给浏览器。大概的代码如下：<?php $time = 86400; if(isset($_SERVER['HTTP_IF_MODIFIED_SINCE'])){ $is_update=0;//判断是否有更新 if($c_time > time()){ header('Cache-Control:max-age='.$time); header("Expires: " . gmdate("D, d M Y H:i:s",time()+$time)." GMT"); header("Last-Modified: " . gmdate("D, d M Y H:i:s") . " GMT"); header('HTTP/1.1 304 Not Modified'); exit(); } } header('Cache-Control:max-age=' . $time); header("Expires: " . gmdate("D, d M Y H:i:s", time() + $time) . " GMT"); header("Last-Modified: " . gmdate("D, d …