使用If-None-Match和Etag协商缓存json动态数据

现代网页大多使用ajax获取动态json数据,有些json数据很大几乎不会修改,这样的数据就适合使用缓存来加快速度,减小流量,降低服务器的负荷。

普通的强缓存要指定时间,比如说24小时,这个时间很难定,因为这些数据虽然平时不会变动,但是一旦变动,因为有浏览器的缓存,页面上依旧使用旧数据,这样极大的限制了缓存的使用。

有没有一种办法既使用缓存,又不会使用旧数据呢?答案就是协商缓存。

协商缓存

协商缓存都会向服务器发送请求,判断缓存数据是否过期,过期的话会返回新的内容,没有过期则使用本地的缓存数据。具体的自己百度一下。实际上这个原来是用在web服务器上用来缓存静态资源的,静态文件都有文件修改时间,能够很简单的实现时间戳。如果要缓存动态数据,需要自己查询数据库来实现时间戳检查。

http1.1 使用 请求头:If-None-Match , 响应头: Etag

只要服务器端能够响应上面的请求头,就可以实现协商缓存。如果服务器返回响应的时候在header加上Etag,那么下次请求该资源的时候,浏览器会在请求头里面自动加上If-None_Match,ajax请求也会自动加上,这个功能就像cookies一样,为每个缓存加上标记。

协商缓存就是判断之前的Etag是否过期,通常使用时间戳来代表这个数据什么时候更改了,如果没有更改就返回304状态码,告诉浏览器继续使用缓存。时间戳可以用数据库中数据的更新时间,一旦该数据被更新了,就会加载新数据。

写成php代码就像下面一样,时间戳需要自己设计,下面的伪代码仅供参考。

	public function checkEtag($etag){
		$_etag = $this->request->header('If-None-Match');
		if ($etag==$_etag) {
            //这个是返回空并设置状态码304
			throw new UserException('',304);
		}
		header('ETag: ' . $etag);
		// 设置Cache-Control头
		header('Cache-Control: max-age=1');
	}


...
//用sql获取数据的时间戳
$timestamp=getTimestamp();
checkEtag('aaaaa');


//原有的业务逻辑
...

我们会发现,协商缓存就是以小博大,先去服务器查询时间戳是否过期。过期了返回新数据,否则就用缓存,这样就始终保持的数据的新鲜度。

你可能感兴趣的:(json,协商缓存,Etag,If-None-Match)