Hanami是一个以简洁和分层架构著称的Ruby Web框架,它的控制器层由一个个细粒度的Action组成。在实际项目中,静态资源、公开页面接口往往希望被浏览器或中间代理缓存一段时间,以减少重复请求。要实现这一点,最直接的方式就是在响应头中写入过期时间相关的字段。Hanami::Action内置了缓存辅助方法,其中expires方法可以帮我们在Action里一行代码完成Expires响应头的设置。

一、Expires响应头的原理与作用
Expires是HTTP/1.0时代就存在的响应头,它的值是一个标准的HTTP日期,表示在这个时间点之前,浏览器可以直接使用本地缓存副本,而不必再向服务器发起请求。例如Expires: Thu, 01 Dec 2025 16:00:00 GMT,浏览器在该时间前会认为缓存的资源仍然新鲜。
Expires头的核心机制依赖服务器时间与客户端时间的对照。这既是它的优点也是隐患:如果客户端时钟与服务器时钟存在偏差,缓存判定就会出现误差。正因如此,HTTP/1.1引入了Cache-Control头,其中的max-age指令以秒为单位计算相对时间,不依赖具体日期,更加可靠。现代浏览器在两者同时存在时,会优先采用Cache-Control的规则。
在实际项目中,Expires并非没有价值。对于CDN节点、老旧代理服务器或一些只认HTTP/1.0的环境,Expires仍然是被广泛支持的字段。同时设置两个头,可以做到最大程度的兼容,这也是Hanami的缓存辅助方法设计时考虑的场景。
二、Hanami中expires方法的基本用法
Hanami为Action提供了声明式的缓存控制接口。在Action类中调用expires方法并传入时间参数,框架会自动为响应生成Expires头。最基础的用法是传入一个整数,表示从当前时刻起经过多少秒后过期。
class Web::Controllers::Home::Index
include Web::Action
# 响应在3600秒(1小时)后过期
expires 3600
def call(params)
self.body = "welcome"
end
end
上述代码执行后,响应头中会包含类似Expires: Wed, 15 Nov 2023 08:30:00 GMT的内容。框架会根据服务器当前时间加上传入的秒数,自动计算并格式化GMT时间,开发者不需要手动处理日期格式化。
除了整数秒,也可以传入一个Time对象作为绝对过期时刻,这在需要与业务时间点对齐的场景(例如活动页在某个时刻失效)下非常有用:
class Web::Controllers::Promos::Show
include Web::Action
# 活动页在指定时刻整体失效
expires Time.parse("2025-12-31 23:59:59 +0800")
def call(params)
self.body = render
end
end
三、进阶配置与常见踩坑点
expires还支持附加选项,用来同时控制Cache-Control头的行为。例如传入public: true表示响应可以被共享缓存(如CDN)存储,private: true则限制只有浏览器本身可以缓存,no_cache: true则要求每次都重新验证。
class Api::Controllers::Assets::Manifest
include Api::Action
# 同时写入Cache-Control: public, max-age=86400
expires 86400, public: true
def call(params)
self.body = manifest_json
end
end
有几个细节需要特别注意。第一,expires是类级别的声明,作用于该Action的所有请求,如果在方法内部需要动态调整过期时间,应通过self.headers手动写入响应头,而不是在call方法里再调用expires。第二,对于包含用户个性化内容的页面,务必使用private或干脆不设置缓存,否则共享缓存可能把A用户的数据返回给B用户,造成信息泄露。第三,expires 0和expires未设置是两回事,前者表示立即过期,常用于强制刷新场景,后者则表示不做任何缓存控制。
另外要理解Hanami对HTTP头的组合逻辑:当你通过expires设置了过期时间,又单独用self.headers['Cache-Control'] = 'no-store'覆盖时,后写入的值会生效,最终响应以最后一次设置为准。建议在项目里统一封装缓存策略,例如为纯静态接口定义一个CachedAction基类,把expires配置收敛到一处,避免各Action各自为政导致缓存行为混乱。
合理使用Expires和Cache-Control,是低成本提升页面性能的手段。在Hanami中借助expires辅助方法,几行代码就能让浏览器和CDN为你分担流量压力,值得在每个Web项目中认真规划。
HanamiExpires响应头缓存控制修改时间:2026-09-08 15:15:01