Spec-Zone.ru › Ruby on Rails 8.0

модуль ActionController::ConditionalGet

Включенные модули:
ActionController::Head

Публичные методы экземпляров

expires_in(seconds, options = {}) Показать исходный код
# 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

Устанавливает заголовок Cache-Control, перезаписывая существующие директивы. Этот метод также обеспечит заголовок HTTP Date для совместимости с клиентом.

По умолчанию устанавливается директива private, чтобы промежуточные кэши не кэшировали ответ.

Параметры

:public

Если true, заменяет стандартную директиву private на директиву public.

:must_revalidate

Если true, добавляет директиву must-revalidate.

:stale_while_revalidate

Устанавливает значение директивы stale-while-revalidate.

:stale_if_error

Устанавливает значение директивы stale-if-error.

:immutable

Если true, добавляет директиву 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
expires_now() Показать исходный код
# File actionpack/lib/action_controller/metal/conditional_get.rb, line 309
def expires_now
  response.cache_control.replace(no_cache: true)
end

Устанавливает заголовок HTTP 1.1 Cache-Control со значением no-cache. Это означает, что ресурс будет помечен как устаревший, поэтому клиенты всегда должны проверять его. Промежуточные/браузерные кэши всё ещё могут хранить актив.

fresh_when(object = nil, etag: nil, weak_etag: nil, strong_etag: nil, last_modified: nil, public: false, cache_control: {}, template: nil) Показать исходный код
# 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

Устанавливает etag, last_modified, или оба в ответе и рендерит 304 Not Modified ответ, если запрос уже свежий.

Параметры

:etag

Устанавливает «слабый» валидатор ETag в ответе. См. параметр :weak_etag.

:weak_etag

Устанавливает «слабый» валидатор ETag в ответе. Запросы, которые указывают заголовок If-None-Match, могут получить 304 Not Modified ответ, если ETag совпадает точно.

Слабый ETag указывает на семантическое соответствие, а не байтовое равенство, поэтому он подходит для кэширования HTML-страниц в браузерных кэшах. Он не может быть использован для ответов, которые должны быть точно такими же, как байты, например, для обработки Range запросов внутри PDF-файла.

:strong_etag

Устанавливает «сильный» валидатор ETag в ответе. Запросы, которые указывают заголовок If-None-Match, могут получить 304 Not Modified ответ, если ETag совпадает точно.

Сильный ETag подразумевает точное равенство – ответ должен совпадать байт в байт. Это необходимо для обработки Range запросов внутри больших видео- или PDF-файлов, например, или для совместимости с некоторыми CDN, которые не поддерживают слабые ETags.

:last_modified

Устанавливает «слабый» валидатор последнего обновления в ответе. Последующие запросы, которые указывают заголовок If-Modified-Since, могут получить 304 Not Modified ответ, если last_modified <= If-Modified-Since.

:public

По умолчанию заголовок Cache-Control является приватным. Установите этот параметр в true, если вы хотите, чтобы приложение можно было кэшировать другими устройствами, например, кэшами прокси.

:cache_control

Если указано, перепишет существующий заголовок Cache-Control. Список директив Cache-Control см. в статье на MDN.

:template

По умолчанию в ETags включен хэш шаблона для текущего контроллера/действия. Если действие рендерит другой шаблон, вы можете включить его хэш вместо него. Если действие вообще не рендерит шаблон, вы можете передать template: false чтобы пропустить попытку проверки хэша шаблона.

Примеры

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

Это отправит 304 Not Modified ответ, если запрос указывает совпадающий ETag и If-Modified-Since заголовок. В противном случае он рендерит шаблон 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" }
http_cache_forever(public: false) { || ... } Показать исходный код
# 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

Кэшировать или выполнить блок. Предполагается, что кэш никогда не истекает.

Вы можете использовать этот метод, когда у вас есть HTTP-ответ, который никогда не изменяется, и браузер и прокси должны кэшировать его неограниченно.

  • public: По умолчанию HTTP-ответы являются приватными, кэшируются только в браузере пользователя. Чтобы разрешить кэширование ответа прокси, установите true чтобы указать, что они могут предоставлять кэшированный ответ всем пользователям.

no_store() Показать исходный код
# File actionpack/lib/action_controller/metal/conditional_get.rb, line 331
def no_store
  response.cache_control.replace(no_store: true)
end

Устанавливает заголовок HTTP 1.1 Cache-Control со значением no-store. Это означает, что ресурс не может быть сохранён в кэше.

stale?(object = nil, **freshness_kwargs) Показать исходный код
# 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

Устанавливает 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

© 2004–2021 David Heinemeier Hansson
Licensed under the MIT License.

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API