модуль ActionController::ConditionalGet
Общедоступные методы экземпляра
# File actionpack/lib/action_controller/metal/conditional_get.rb, line 276
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 Устанавливает заголовок кэширования HTTP 1.1 Cache-Control. По умолчанию устанавливается инструкция private, чтобы промежуточные кэши не кэшировали ответ.
expires_in 20.minutes expires_in 3.hours, public: true expires_in 3.hours, public: true, must_revalidate: true
Этот метод перезапишет существующий заголовок Cache-Control. Для получения других возможностей обратитесь к www.w3.org/Protocols/rfc2616/rfc2616-sec14.html.
Расширения HTTP Cache-Control для устаревших данных. См. tools.ietf.org/html/rfc5861. Это помогает кэшировать ресурс и предоставлять его во время перепроверки и/или при возвращении ошибки.
expires_in 3.hours, public: true, stale_while_revalidate: 60.seconds expires_in 3.hours, public: true, stale_while_revalidate: 60.seconds, stale_if_error: 5.minutes
Другие значения расширений HTTP Cache-Control: developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Cache-Control. Любые дополнительные пары ключ-значение конкатенируются в заголовок `Cache-Control` в ответе:
expires_in 3.hours, public: true, "s-maxage": 3.hours, "no-transform": true
Метод также гарантирует наличие заголовка HTTP Date для совместимости с клиентом.
# File actionpack/lib/action_controller/metal/conditional_get.rb, line 294 def expires_now response.cache_control.replace(no_cache: true) end
Устанавливает заголовок HTTP 1.1 Cache-Control со значением no-cache. Это означает, что ресурс будет помечен как устаревший, поэтому клиенты всегда должны повторно проверять его. Промежуточные кэши/браузеры могут по-прежнему хранить ресурс.
# File actionpack/lib/action_controller/metal/conditional_get.rb, line 117
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. Для получения дополнительных возможностей обратитесь к www.w3.org/Protocols/rfc2616/rfc2616-sec14.html. -
:templateПо умолчанию в ETags включен дайджест шаблона для текущего контроллера/действия. Если действие использует другой шаблон, вы можете включить его дайджест вместо него. Если действие вообще не использует шаблон, вы можете передатьtemplate: false, чтобы пропустить попытку проверки дайджеста шаблона.
Пример:
def show @article = Article.find(params[:id]) fresh_when(etag: @article, last_modified: @article.updated_at, public: true) end
Это отобразит шаблон show, если запрос не отправляет соответствующий заголовок ETag или If-Modified-Since, и просто 304 Not Modified ответ, если есть совпадение.
Вы также можете передать просто запись. В этом случае last_modified будет установлено вызовом updated_at, и etag передачей самого объекта.
def show @article = Article.find(params[:id]) fresh_when(@article) end
Вы также можете передать объект, который отвечает на maximum, например, коллекцию активных записей. В этом случае last_modified будет установлено вызовом maximum(:updated_at) к коллекции (временная метка последней обновлённой записи), а etag передачей самого объекта.
def index @articles = Article.all fresh_when(@articles) end
При передаче записи или коллекции вы по-прежнему можете установить заголовок public:
def show @article = Article.find(params[:id]) fresh_when(@article, public: true) end
При перезаписи заголовка 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 306
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 Кэшировать или использовать блок. Кэш не должен истекать.
Этот метод можно использовать, когда у вас есть HTTP-ответ, который никогда не меняется, и браузер и прокси должны кэшировать его неопределённо.
-
public: По умолчанию HTTP-ответы являются приватными, кэшируются только в браузере пользователя. Чтобы разрешить прокси-серверам кэшировать ответ, установитеtrueдля указания, что они могут предоставлять кэшированный ответ всем пользователям.
# File actionpack/lib/action_controller/metal/conditional_get.rb, line 316 def no_store response.cache_control.replace(no_store: true) end
Устанавливает заголовок HTTP 1.1 Cache-Control со значением no-store. Это означает, что ресурс не должен храниться в кэше.
# File actionpack/lib/action_controller/metal/conditional_get.rb, line 249 def stale?(object = nil, **freshness_kwargs) fresh_when(object, **freshness_kwargs) !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. Для получения дополнительных возможностей обратитесь к www.w3.org/Protocols/rfc2616/rfc2616-sec14.html. -
:templateПо умолчанию в ETags включен дайджест шаблона для текущего контроллера/действия. Если действие использует другой шаблон, вы можете включить его дайджест вместо него. Если действие вообще не использует шаблон, вы можете передатьtemplate: falseчтобы пропустить попытку проверки дайджеста шаблона.
Пример:
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
Вы также можете передать просто запись. В этом случае last_modified будет установлено вызовом updated_at, и etag передачей самого объекта.
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
Вы также можете передать объект, который отвечает на maximum, например, коллекцию активных записей. В этом случае last_modified будет установлено вызовом maximum(:updated_at) к коллекции (временная метка последней обновлённой записи), а etag передачей самого объекта.
def index
@articles = Article.all
if stale?(@articles)
@statistics = @articles.really_expensive_call
respond_to do |format|
# all the supported formats
end
end
end
При передаче записи или коллекции вы по-прежнему можете установить заголовок public:
def show
@article = Article.find(params[:id])
if stale?(@article, public: true)
@statistics = @article.really_expensive_call
respond_to do |format|
# all the supported formats
end
end
end
При перезаписи заголовка 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.