3

私は現在、HerokuのCedarスタックでOctopress(Jekyllに基づく)サイトを実行しています。コードはここにあります:https ://github.com/elithrar/octopress

Cache-Controlファイルタイプに基づいてヘッダーを選択的に適用したい:

  • .htmlファイルはの値を取得しますpublic, max-age=3600
  • .css|.js|.png|.ico(etc)の値を取得します-あるいは、このルールをディレクトリpublic, max-age=604800から提供されるものすべてに適用したいと思います。/stylesheets', '/javascripts', '/imgs'

運がなく、両方set :static_cache_control , [:public, :max_age => 3600]とバニラcache_control :public, :max_age => 3600ステートメントだけを使用しました。

public, max-age=3600記事自体を設定する/2012/lazy-sundays/ことができましたが(例)、CSS / JSに適用するヘッダーを取得できませんでした(例/stylesheets/screen.css) 。

config.ruは現在このように見えます(更新されました):

require 'bundler/setup'
require 'sinatra/base'

# The project root directory
$root = ::File.dirname(__FILE__)

class SinatraStaticServer < Sinatra::Base

  get(/.+/) do
    cache_control :public, :max_age => 7200
    send_sinatra_file(request.path) {404}
  end

  not_found do
    send_sinatra_file('404.html') {"Sorry, I cannot find #{request.path}"}
    cache_control :no_cache, :max_age => 0
  end

  def send_sinatra_file(path, &missing_file_block)
    file_path = File.join(File.dirname(__FILE__), 'public',  path)
    file_path = File.join(file_path, 'index.html') unless file_path =~ /\.[a-z]+$/i  
    File.exist?(file_path) ? send_file(file_path) : missing_file_block.call
  end

end

use Rack::Deflater

run SinatraStaticServer
4

2 に答える 2

6

静的アセットに長い有効期限ヘッダーを設定する方法と、Herokuのメインコンテンツに任意の有効期限ヘッダーを設定する方法は次のとおりです。

gemfile:

gem 'rack-contrib'

config.ru:

require 'rack/contrib'

get '*.html' do |page|
  # whatever code you need to serve up your main pages
  # goes here... use Rack::File I guess.
  page
end


# Set content headers for that content...
before do
  expires 5001, :public, :must_revalidate
end


# Assets in /static/stylesheets (domain.com/stylesheets) 
# are served by Rack StaticCache, with a default 2 year expiry.

use Rack::StaticCache, :urls => ["/stylesheets"], :root => Dir.pwd + '/static'

run Sinatra::Application

デフォルトでは、URLの配列(静的/スタイルシート、静的/画像など)にリストされているコンテンツの有効期限が2年になります。

/publicから/staticに移動する必要があります。そうしないと、Herokuのnginx構成(この種の設定を実際に適用するのに適切な場所...)と不必要に戦うことになります。

Rack Contribを使用しないようにしようとしているとおっしゃっていましたが、それは意味がありません。これを行うために小さな90行のライブラリを使用しても害はありませんhttps://github.com/rack/rack-contrib/blob/master/lib/rack/contrib/static_cache.rb

「正しい」方法は、nginxを構成できる環境で静的コンテンツをホストすることです。次善の方法は、静的ファイルパスの名前を変更して、herokuがそれを無視するようにし、rackstaticを使用して必要なヘッダーを持つ静的ファイルを提供することです。

-

また、明確にするために、パブリックフォルダーの名前を別の名前に変更するだけで、ルートを介してこれを行うことができ、通常のSinatraの有効期限が機能します。ただし、冗長性が少ないため、StaticCacheを使用します。(本当の問題は、Herokuがnginxに公開リクエストのアプリとの通信を許可しないことです/と私は信じています。)

于 2012-07-19T08:49:13.827 に答える
1

私はシナトラにほとんど精通していませんが、このようなものでうまくいくと思います。

class SinatraStaticServer < Sinatra::Base
  before '*.html' do
    response.headers['Cache-Control'] = 'public, max-age=3600'
  end

  before %r{\.(css)|(js)|(png)|(ico)} do
    response.headers['Cache-Control'] = 'public, max-age=604800'
  end

  # ...
end

更新:上記でヘッダーが正常に追加されていないとおっしゃったときに、さらに詳しく調べました。問題は、Sinatraがpublic/アプリを経由せずにファイルを自動的に提供していたため、ヘッダーが追加されていなかったことであると判断しました。私の解決策は、静的ファイルをからに移動し、public/それに応じpublic/public/て調整することでした。send_sinatra_file

class SinatraStaticServer < Sinatra::Base
  # ...

  def send_sinatra_file(path, &missing_file_block)
    file_path = File.join(File.dirname(__FILE__), 'public/public',  path)
    file_path = File.join(file_path, 'index.html') unless file_path =~ /\.[a-z]+$/i
    File.exist?(file_path) ? send_file(file_path) : missing_file_block.call
  end

  # ...
end

これが私のマシンで動作することを確認しました。response.headers['Cache-Control']私は答えの最初の部分で使用したものであり、あなたが試したものではないことに注意してください。ただし、ブロックset :static_cache_control内で1回だけ実行することを意図していると思います。configure do

また、この現在の設定では、上記に一致する404は、たとえばnonexistant.png、Cache-Controlヘッダーがまだ存在する状態で404ステータスを提供することに注意してください。私はそれを回避するいくつかの方法を見ることができますが、私はあなたがそうすることを理解しているので、私はそれを指摘し、あなたが好きなようにそれを扱うだろうと考えています。

于 2012-07-16T23:12:36.423 に答える