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

实例公共方法

expires_in(seconds, options = {})

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

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

选项

:public

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

:must_revalidate

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

:stale_while_revalidate

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

:stale_if_error

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

任何其他键值对都将作为指令连接起来。有关支持的 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 274
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),
  )
  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 292
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 128
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 304
def http_cache_forever(public: false)
  expires_in 100.years, public: public

  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 314
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 227
def stale?(object = nil, **freshness_kwargs)
  fresh_when(object, **freshness_kwargs)
  !request.fresh?(response)
end