【问题标题】:Setting public_file_server.headers except for some files设置 public_file_server.headers 除了一些文件
【发布时间】:2019-03-17 03:40:24
【问题描述】:

我在 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 级别进行配置?

【问题讨论】:

    标签: ruby-on-rails amazon-cloudfront cache-control


    【解决方案1】:

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

    因为 CloudFront 本身不允许添加或更改标头,所以我需要一个应用级别的解决方案。经过一番研究,我在blogpost 中找到了解决方案。我们的想法是通过public_file_server.headers 设置标题并添加一个中间件来更改ServiceWorker 文件。

    另外,你写的是maxage=,应该是max-age=

    这是我使用的代码:

    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
    

    【讨论】:

      猜你喜欢
      • 2019-10-07
      • 2023-03-29
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-08-02
      相关资源
      最近更新 更多