Установка public_file_server.headers за исключением некоторых файлов - PullRequest
0 голосов
/ 12 октября 2018

Я использую это в production.rb:

config.public_file_server.headers = {
  'Cache-Control' => 'public, s-maxage=31536000, maxage=31536000',
  'Expires'       => "#{1.year.from_now.to_formatted_s(:rfc822)}"
}

Я использую публичные файлы через cdn.mydomain.com, который читает с www.mydomain.com и копирует элемент управления кэша с www.mydomain.com, который я установил с помощью public_file_server.headers.

Проблема в том, что я хочу, чтобы некоторые файлы из / public не имели такого контроля кэша, например, для моего service-worker.js

Есть ли способ установить эти элементы управления кэшем, например, только для одной папки в / public?

Другим решением было бы удалить эту конфигурацию public_file_server.headers и установить элемент управления кэшем на уровне cdn.(Я использую cdn.mydomain.com/publicfile) и оставляю www.mydomain.com/serviceworker без контроля кэша для работника сервиса.

Но, может быть, есть шанс настроить это на уровне Rails?

1 Ответ

0 голосов
/ 17 октября 2018

У меня была точно такая же проблема: PWA собран с Rails с использованием CDN (Cloudfront).Для активов, которые я хочу использовать, заголовки кеша с большим сроком действия истекают, но ServiceWorker требуется Cache-control: No-cache.

. Поскольку CloudFront не позволяет самостоятельно добавлять или изменять заголовки, мне нужно решение на уровне приложения.,После некоторых исследований я нашел решение в blogpost .Идея состоит в том, чтобы установить заголовки через public_file_server.headers и добавить промежуточное программное обеспечение, чтобы изменить это для файла ServiceWorker.

Вот код, который я использую:

production.rb:

config.public_file_server.enabled = ENV['RAILS_SERVE_STATIC_FILES'].present?
config.public_file_server.headers = {
  'Cache-Control' => 'public, s-maxage=31536000, max-age=15552000',
  'Expires' => 1.year.from_now.to_formatted_s(:rfc822)
}

if ENV['RAILS_SERVE_STATIC_FILES'].present?
  config.middleware.insert_before ActionDispatch::Static, ServiceWorkerManager, ['sw.js']
end

app / middleware / service_worker_manager.rb:

# Taken from https://codeburst.io/service-workers-rails-middleware-841d0194144d
#
class ServiceWorkerManager
  # We’ll pass 'service_workers' when we register this middleware.
  def initialize(app, service_workers)
    @app = app
    @service_workers = service_workers
  end

  def call(env)
    # Let the next middleware classes & app do their thing first…
    status, headers, response = @app.call(env)
    dont_cache = @service_workers.any? { |worker_name| env['REQUEST_PATH'].include?(worker_name) }

    # …and modify the response if a service worker was fetched.
    if dont_cache
      headers['Cache-Control'] = 'no-cache'
      headers.except!('Expires')
    end

    [status, headers, response]
  end
end
...