跳至内容 跳至搜索
命名空间
方法
E
F
H
N
S
包含的模块

实例公开方法

expires_in(seconds, options = {})

设置 Cache-Control 头部,覆盖现有的指令。此方法还将确保 HTTP Date 头部,以确保客户端兼容性。

默认情况下,会发出 private 指令,因此中间缓存不得缓存响应。

选项

:public

如果为真,则用 public 指令替换默认的 private 指令。

:must_revalidate

如果为真,则添加 must-revalidate 指令。

:stale_while_revalidate

设置 stale-while-revalidate 指令的值。

:stale_if_error

设置 stale-if-error 指令的值。

:immutable

如果为真,则添加 immutable 指令。

任何其他键值对都被连接为指令。有关支持的 Cache-Control 指令的列表,请参阅 MDN 上的文章

示例

expires_in 10.minutes
# => Cache-Control: max-age=600, private

expires_in 10.minutes, public: true
# => Cache-Control: max-age=600, public

expires_in 10.minutes, public: true, must_revalidate: true
# => Cache-Control: max-age=600, public, must-revalidate

expires_in 1.hour, stale_while_revalidate: 60.seconds
# => Cache-Control: max-age=3600, private, stale-while-revalidate=60

expires_in 1.hour, stale_if_error: 5.minutes
# => Cache-Control: max-age=3600, private, stale-if-error=300

expires_in 1.hour, public: true, "s-maxage": 3.hours, "no-transform": true
# => Cache-Control: max-age=3600, public, s-maxage=10800, no-transform=true
# File actionpack/lib/action_controller/metal/conditional_get.rb, line 290
def expires_in(seconds, options = {})
  response.cache_control.delete(:no_store)
  response.cache_control.merge!(
    max_age: seconds,
    public: options.delete(:public),
    must_revalidate: options.delete(:must_revalidate),
    stale_while_revalidate: options.delete(:stale_while_revalidate),
    stale_if_error: options.delete(:stale_if_error),
    immutable: options.delete(:immutable),
  )
  options.delete(:private)

  response.cache_control[:extras] = options.map { |k, v| "#{k}=#{v}" }
  response.date = Time.now unless response.date?
end

expires_now()

设置 HTTP 1.1 Cache-Control 头部为 no-cache。这意味着资源将被标记为陈旧,因此客户端必须始终重新验证。中间/浏览器缓存可能仍然存储资源。

# File actionpack/lib/action_controller/metal/conditional_get.rb, line 309
def expires_now
  response.cache_control.replace(no_cache: true)
end

fresh_when(object = nil, etag: nil, weak_etag: nil, strong_etag: nil, last_modified: nil, public: false, cache_control: {}, template: nil)

在响应中设置 etaglast_modified 或两者,如果请求已经新鲜,则渲染 304 Not Modified 响应。

选项

:etag

在响应中设置“弱”ETag 验证器。请参阅 :weak_etag 选项。

:weak_etag

在响应中设置“弱”ETag 验证器。如果 ETag 完全匹配,则指定了 If-None-Match 头部的请求可能会收到 304 Not Modified 响应。

弱 ETag 表示语义等效性,而不是逐字节的等效性,因此它们适合在浏览器缓存中缓存 HTML 页面。它们不能用于必须逐字节相同的响应,例如,在 PDF 文件中提供 Range 请求。

:strong_etag

在响应中设置“强”ETag 验证器。如果 ETag 完全匹配,则指定了 If-None-Match 头部的请求可能会收到 304 Not Modified 响应。

强 ETag 表示精确的相等性 - 响应必须逐字节匹配。例如,对于在大型视频或 PDF 文件中提供 Range 请求,或者对于与不支持弱 ETag 的某些 CDN 兼容,这是必需的。

:last_modified

在响应中设置“弱”最后更新验证器。如果 last_modified <= If-Modified-Since,则指定了 If-Modified-Since 头部的后续请求可能会收到 304 Not Modified 响应。

:public

默认情况下,Cache-Control 头部是私有的。如果您希望您的应用程序可以被其他设备(例如代理缓存)缓存,请将此选项设置为 true

:cache_control

如果提供,将覆盖现有的 Cache-Control 头部。有关 Cache-Control 指令的列表,请参阅 MDN 上的文章

:template

默认情况下,当前控制器/操作的模板摘要包含在 ETag 中。如果操作渲染不同的模板,则可以改为包含其摘要。如果操作根本不渲染模板,则可以传递 template: false 以跳过任何尝试检查模板摘要。

示例

def show
  @article = Article.find(params[:id])
  fresh_when(etag: @article, last_modified: @article.updated_at, public: true)
end

如果请求指定匹配的 ETag 和 If-Modified-Since 头部,这将发送 304 Not Modified 响应。否则,它将渲染 show 模板。

您也可以只传递一条记录

def show
  @article = Article.find(params[:id])
  fresh_when(@article)
end

etag 将被设置为记录,last_modified 将被设置为记录的 updated_at

您也可以传递响应 maximum 的对象,例如记录的集合

def index
  @articles = Article.all
  fresh_when(@articles)
end

在这种情况下,etag 将被设置为集合,last_modified 将被设置为 maximum(:updated_at)(更新时间最近的记录的时间戳)。

传递记录或集合时,您仍然可以指定其他选项,例如 :public:cache_control

def show
  @article = Article.find(params[:id])
  fresh_when(@article, public: true, cache_control: { no_cache: true })
end

以上将设置 Cache-Control: public, no-cache 在响应中。

渲染与控制器/操作的默认模板不同的模板时,您可以指示要包含在 ETag 中的摘要

before_action { fresh_when @article, template: "widgets/show" }
# File actionpack/lib/action_controller/metal/conditional_get.rb, line 137
def fresh_when(object = nil, etag: nil, weak_etag: nil, strong_etag: nil, last_modified: nil, public: false, cache_control: {}, template: nil)
  response.cache_control.delete(:no_store)
  weak_etag ||= etag || object unless strong_etag
  last_modified ||= object.try(:updated_at) || object.try(:maximum, :updated_at)

  if strong_etag
    response.strong_etag = combine_etags strong_etag,
      last_modified: last_modified, public: public, template: template
  elsif weak_etag || template
    response.weak_etag = combine_etags weak_etag,
      last_modified: last_modified, public: public, template: template
  end

  response.last_modified = last_modified if last_modified
  response.cache_control[:public] = true if public
  response.cache_control.merge!(cache_control)

  head :not_modified if request.fresh?(response)
end

http_cache_forever(public: false)

缓存或生成块。缓存应该永远不会过期。

当您拥有一个永远不会改变的 HTTP 响应时,可以使用此方法,浏览器和代理应该无限期地缓存它。

  • public: 默认情况下,HTTP 响应是私有的,仅在用户的 Web 浏览器上缓存。要允许代理缓存响应,请设置 true 表示它们可以向所有用户提供缓存的响应。

# File actionpack/lib/action_controller/metal/conditional_get.rb, line 321
def http_cache_forever(public: false)
  expires_in 100.years, public: public, immutable: true

  yield if stale?(etag: request.fullpath,
                  last_modified: Time.new(2011, 1, 1).utc,
                  public: public)
end

no_store()

设置 HTTP 1.1 Cache-Control 头部为 no-store。这意味着资源可能不会存储在任何缓存中。

# File actionpack/lib/action_controller/metal/conditional_get.rb, line 331
def no_store
  response.cache_control.replace(no_store: true)
end

stale?(object = nil, **freshness_kwargs)

在响应中设置 etag 和/或 last_modified,并根据请求对其进行检查。如果请求与提供的选项不匹配,则它被视为陈旧,并且响应应该从头开始渲染。否则,它很新鲜,并且会发送 304 Not Modified

选项

有关支持的选项,请参阅 fresh_when

示例

def show
  @article = Article.find(params[:id])

  if stale?(etag: @article, last_modified: @article.updated_at)
    @statistics = @article.really_expensive_call
    respond_to do |format|
      # all the supported formats
    end
  end
end

您也可以只传递一条记录

def show
  @article = Article.find(params[:id])

  if stale?(@article)
    @statistics = @article.really_expensive_call
    respond_to do |format|
      # all the supported formats
    end
  end
end

etag 将被设置为记录,last_modified 将被设置为记录的 updated_at

您也可以传递响应 maximum 的对象,例如记录的集合

def index
  @articles = Article.all

  if stale?(@articles)
    @statistics = @articles.really_expensive_call
    respond_to do |format|
      # all the supported formats
    end
  end
end

在这种情况下,etag 将被设置为集合,last_modified 将被设置为 maximum(:updated_at)(更新时间最近的记录的时间戳)。

传递记录或集合时,您仍然可以指定其他选项,例如 :public:cache_control

def show
  @article = Article.find(params[:id])

  if stale?(@article, public: true, cache_control: { no_cache: true })
    @statistics = @articles.really_expensive_call
    respond_to do |format|
      # all the supported formats
    end
  end
end

以上将设置 Cache-Control: public, no-cache 在响应中。

渲染与控制器/操作的默认模板不同的模板时,您可以指示要包含在 ETag 中的摘要

def show
  super if stale?(@article, template: "widgets/show")
end
# File actionpack/lib/action_controller/metal/conditional_get.rb, line 236
def stale?(object = nil, **freshness_kwargs)
  fresh_when(object, **freshness_kwargs)
  !request.fresh?(response)
end