除某些文件外,设置public_file_server.headers

Nic*_*vre 5 ruby-on-rails cache-control amazon-cloudfront

我在production.rb中使用它:

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

我通过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级别配置它?

Geo*_*ann 8

我遇到了完全相同的问题:使用 CDN (Cloudfront) 使用 Rails 构建的 PWA。对于我想使用远期到期的缓存标头的资产,但 ServiceWorker 需要Cache-control: No-cache.

由于 CloudFront 不允许自行添加或更改标头,因此我需要应用程序级别的解决方案。经过一番研究,我在一篇博文中找到了解决方案。这个想法是通过设置标头public_file_server.headers并添加一个中间件来更改 ServiceWorker 文件的这一点。

这是我使用的代码:

生产.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
Run Code Online (Sandbox Code Playgroud)

应用程序/中间件/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
Run Code Online (Sandbox Code Playgroud)