问候,
如何在 Ruby on Rails v2.3.5 中关闭 ETag(s)
当我向 RoR/Mongrel 发出直接请求时,会出现一个 ETag 标头。
TIA,
-丹尼尔
问候,
如何在 Ruby on Rails v2.3.5 中关闭 ETag(s)
当我向 RoR/Mongrel 发出直接请求时,会出现一个 ETag 标头。
TIA,
-丹尼尔
容易得多:
config.middleware.delete Rack::ETag
放入before_filterresponse.etag = nil
不起作用。etag 是在发送响应之前生成的(它是从正文中计算出来的,所以在所有渲染完成之后)。
在这个猴子补丁中禁用 etag 使用和生成(从而节省在 md5 中花费的时间)的正确解决方法:
module ActionController
class Request
# never match any incomming etag
def etag_matches?(etag)
false
end
end
class Response
# fake rails that our response already has an etag set and so none is generated automatically
def etag?
true
end
end
end
对象上有一个etag
setter 方法,ActionController::Response
如果 ETag HTTP 标头为空,它将删除它,因此您应该能够在控制器中将其清除(可能在之前的过滤器中):
response.etag = nil
我不认为它们是默认开启的。
我的理解是需要使用 stale?/fresh_when 调用或类似方法明确设置它们。
我在 WEBrick 上的 Rails 4 中工作,试图获得对缓存的响应,直到它在每天的特定时间过期。看起来自动生成的 ETag 干扰了过期缓存,这就是我搜索这个答案的原因。我在这里没有发现任何有用的东西,但我确实解决了我的问题,所以我会分享。
tl;dr 设置Last-Modified
标题
但是设置成什么?在我的情况下,我试图优化一个 Web 服务,该服务返回一个每天在同一时间运行的进程的结果。我的响应标题最终看起来像这样:
response.headers['Cache-Control'] = "max-age=86400"
response.headers['Expires'] = getCacheTime
response.headers['Last-Modified'] = getLastModified
首先,您要显式编写Cache-Control
标头以覆盖默认值。我将我的设置为 24 小时,以与我的到期标题的最大值一致。我用一个看起来像这样的函数设置了过期标头:
def getCacheTime
now = Time.now.utc
cacheTime = Time.utc(now.year, now.month, now.day, 22, 00, 00)
if now > cacheTime
cacheTime = cacheTime + (60 * 60 * 24)
end
cacheTime.httpdate
end
getLastModified函数返回的时间正好比getCacheTime函数少 24 小时。至少在我当前的开发环境中,设置它似乎会抑制 ETag(另一个验证缓存标头)。
为什么不在应用程序控制器中添加一个 before_filter 来将 etag 设置为 nil?