Grails中如何缓存从数据库读取的图片?
实现数据库存储图片的浏览器缓存
要让从数据库读取的图片被浏览器缓存,核心是给响应添加HTTP缓存头,并处理浏览器的缓存验证请求(返回304 Not Modified)。以下是具体实现步骤:
1. 完善FileData域类,添加更新时间字段
首先需要给存储图片的FileData添加记录最后修改时间的字段,作为缓存验证的依据:
class FileData { String path byte[] data Date lastUpdated // 记录资源最后修改时间 static constraints = { path blank: false, unique: true data nullable: false, maxSize: 16_777_215 } static mapping = { autoTimestamp true // 开启Grails自动时间戳维护,自动更新lastUpdated } }
2. 修改控制器uploads方法,添加缓存头与验证逻辑
在返回图片数据前,添加缓存相关响应头,并处理浏览器的缓存验证请求,避免重复传输图片数据:
def uploads(String path) { FileData imageData = FileData.findByPath("/${path}") if (!imageData) { response.sendError(404) return } // 生成ETag:用资源ID+最后更新时间作为唯一标识,内容变化时ETag自动改变 String eTag = "\"${imageData.id}-${imageData.lastUpdated.time}\"" // 设置Last-Modified头:告知浏览器资源最后修改时间 response.setDateHeader("Last-Modified", imageData.lastUpdated.time) // 设置ETag头:资源的唯一标识,比Last-Modified验证更精确 response.setHeader("ETag", eTag) // 设置Cache-Control:允许公共缓存(如CDN、代理),缓存时长设为1年(可按需调整) response.setHeader("Cache-Control", "public, max-age=31536000") // 验证浏览器的缓存请求:如果资源未修改,直接返回304 Not Modified String ifNoneMatch = request.getHeader("If-None-Match") long ifModifiedSince = request.getDateHeader("If-Modified-Since") // 匹配ETag 或者 Last-Modified未过期,返回304 if ((ifNoneMatch != null && ifNoneMatch.equals(eTag)) || (ifModifiedSince != -1 && imageData.lastUpdated.time <= ifModifiedSince + 1000)) { response.sendError(304) return } // 资源有更新,返回图片数据 response.contentType = URLConnection.guessContentTypeFromName(path) ?: 'application/octet-stream' response.getOutputStream().withCloseable { out -> out.write(imageData.data) out.flush() } }
关键缓存头说明
- Cache-Control: public, max-age=31536000:
public:允许CDN、代理服务器等公共缓存节点缓存该资源,提升访问速度;max-age=31536000:告诉浏览器可以直接缓存该资源1年,期间无需向服务器发起请求。
- Last-Modified:记录资源最后修改的时间戳,浏览器下次请求会携带
If-Modified-Since头,服务器对比后判断资源是否更新。 - ETag:资源的唯一标识,当资源内容(或修改时间)变化时ETag会改变,浏览器请求时携带
If-None-Match头,服务器匹配一致则返回304。
额外说明
你当前图片URL中的?1676524906000时间戳参数可以保留,当需要强制刷新缓存(比如更新图片内容)时,修改这个时间戳即可让浏览器重新请求新资源;配合上面的缓存头,正常情况下浏览器会优先使用本地缓存,无需重复下载。
内容的提问来源于stack exchange,提问作者kofhearts
相关产品推荐
相关产品推荐

