модуль ActionController::ConditionalGet
Открытые методы экземпляров
# File actionpack/lib/action_controller/metal/conditional_get.rb, line 288
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 Устанавливает заголовок 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.
Любые дополнительные пары ключ-значение конкатенируются в виде директив. Список поддерживаемых директив 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 306 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 138
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, которые не поддерживают слабые ETag. -
:last_modified -
Устанавливает «слабый» валидатор последнего обновления в ответе. Последующие запросы, которые указывают заголовок
If-Modified-Since, могут получить304 Not Modifiedответ, еслиlast_modified<=If-Modified-Since. -
:public -
По умолчанию заголовок
Cache-Controlявляется приватным. Установите этот параметр вtrue, если вы хотите, чтобы ваше приложение кэшировалось другими устройствами, такими как кэши прокси. -
:cache_control -
В случае задания перепишет существующий заголовок
Cache-Control. СписокCache-Controlдиректив, см. на [странице MDN](developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Cache-Contr ol). -
:template -
По умолчанию, хэш шаблона для текущего контроллера/действия включен в ETag. Если действие отображает другой шаблон, вы можете включить его хэш вместо этого. Если действие вообще не отображает шаблон, вы можете передать
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" }
# File actionpack/lib/action_controller/metal/conditional_get.rb, line 318
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 328 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 237 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.