主流浏览器都有缓存机制,主要基于HTTP协议定义的缓存策略。对于一定时间内不发生变动的文档缓存起来,对于下次请求,就可以直接返回缓存的结果。使用缓存有以下好处:

1、减少冗余的数据传输,节省网络流量成本
2、减少加载时间,客户能够快速加载页面
3、减少对服务端的压力,避免过载

  我们一般会为静态文件,如图片,脚本,样式表等设置缓存,这样客户端在下次请求时可以减少不必要的网络请求。实际上,我们可以把它用在所有组件上,包括Ajax响应,只要可以确认结果不经常变动,就可以使用缓存策略。

AJAX

  AJAX (Asynchronous JavaScript and XML)表示异步的javascript和XML,实际上,现在最著名的是JSON。Ajax可分为主动请求和被动请求。被动请求指为了将来使用而预先发起的,提前加载一些用户可能用到的数据,来提高用户体验。主动请求,指基于用户当前的操作而发起的请求。

  虽然AJAX是异步请求,但是对于主动请求,用户任然需要等待响应。即便是被动请求可以让用户感受不到等待,但是仍然会有请求,产生流量,对服务端产生压力。

HTTP缓存策略

  HTTP协议通过Header来控制缓存的,包括请求和响应,这里只讲响应的缓存机制。响应缓存主要通过Expires头和Cache-control头来控制。下面按优先级由高到列出一些常见的缓存策略,:

  1. Cache-Control:no-store 不要缓存这个文档
  2. Cache-Control:no-cache 保存文档,但是需要与服务端再验证才能使用
  3. Cache-control:max-age 缓存最长保存时间,单位是秒
  4. Expires:日期 根据日期判断过期,由于客户端和服务器日期可能不同步,不推荐使用

缓存过期检测

  为了防止使用了过期的数据,必须要为缓存设置过期时间,当缓存过期时,需要向服务器请求新的数据。但实际上,虽然缓存过期了,但是服务器的数文档并没有变动,并不需要返回整个文档。因此客户端可以让服务端在改变文档的情况下才发送整个文档。这种特殊请求就是有条件的请求。条件请求一般使用Last-Modified/If-Modified-Since 和 Etag/If-None-Match。

  Last-Modified表示文档的最后修改日期,当缓存过期了,客户端向服务器发送If-Modified-Since:Last-Modified的值进行条件请求,当服务端在这段时间没有修改文档,那么就返回不包含主体的304响应,否则就返回新的文档。

   ETag 则是一个唯一文件标识符,每次文件修改后都会生成一个新的 ETag,因此也可以根据Etag的值来判断文档有没有更新。和最后修改时间检测类似。

  如果响应首部仅包含Last-Modified,就使用If-Modified-Since验证,如果仅包含ETag,那么使用If-None-Match来验证。如果两者都提供了,那么客户端就应该同时发送两种验证。

基于Flask的缓存响应

def make_cache_control_response(json_data):
#json_data可能来自数据库或者服务端缓存(如redis等),也可能是新生成的json数据
resp = make_response()
resp.headers['Content-Type'] = 'application/json'
resp.cache_control.max_age = 600 #最长缓存600秒
if json_data.get('from_cache'): #来自服务端缓存
del json_data['from_cache']
last_modified = json_data.get('cache_time', 0)
if last_modified:
del json_data['cache_time']
resp.last_modified = datetime.fromtimestamp(last_modified) #添加Last-Moditified头
if not resp.last_modified:
resp.last_modified = datetime.now() if request.if_modified_since and request.if_modified_since >= resp.last_modified: #如果是条件请求,并且缓存未过期,返回304响应
return resp, 304
resp.data = json.dumps(json_data)
return resp, 200

最新文章

  1. java提高篇(二十)-----集合大家族
  2. berkeley db replica机制 - election algorithm
  3. iptables 开启80端口
  4. 简单几何(圆与多边形公共面积) UVALive 7072 Signal Interference (14广州D)
  5. HDU1518 Square(DFS)
  6. 主成分分析(PCA)
  7. 《使用shell位置变量进行目录文件的备份小脚本》
  8. Kafka分布式消息模型
  9. 转载 DevOps的基本原则与介绍
  10. listview——显示窗体
  11. 决策树ID3算法
  12. Java中基本数据类型和包装类
  13. 【Python】 文件和操作文件方法
  14. flexbuilder 开发工具
  15. JMeter—常见问题(十四)
  16. 老男孩python学习自修第十四天【序列化和json】
  17. XSS详解
  18. Android LCD(二):LCD常用接口原理篇(转)
  19. web基础----->readonly与disabled的区别
  20. 【问题解决】增加https后 phpcms 分页错误

热门文章

  1. gpart 分区工具
  2. 已知UIScrollView放大后的Frame和放大之前的Frame计算放大的瞄点坐标
  3. Unity3D手游开发日记(6) - 适合移动平台的水深处理
  4. 解题:POI 2018 Prawnicy
  5. 51nod求助
  6. codeforces 217E 【Alien DNA】
  7. PID控制算法的C语言实现三 位置型PID的C语言实现
  8. js浏览器调试方法
  9. git clone 无权限
  10. (转)linux下vi命令修改文件及保存的使用方法