当我在生产模式下部署rails应用程序时,它会将日期时间字符串作为查询参数附加到所有静态资产URL的末尾。这是为了防止浏览器在重新部署应用程序后使用资产的旧日期转换副本。
有没有办法让rails使用旧的时间戳来表示自上次部署以来未更改的资产(以及仅那些未更改的资产)。我想这样做是为了防止用户重新下载那些没有改变的资产。
答案 0 :(得分:13)
默认情况下,Capistrano会触及它认为是“资产”的每个文件。正如您所说,这意味着在每次部署后,rails认为每个资产都已更改,浏览器每次都会下载更新的版本。
您可以使用以下设置在Capistrano中禁用此功能
set :normalize_asset_timestamps, false
如果您使用的是SVN,那么您文件的修改日期应该反映它们在您的存储库中最后修改的日期,因此应该是完美的。
如果您使用的是Apache,可以添加类似这样的内容,以便真正让缓存工作。这有助于告诉浏览器依赖“缓存控制”指令,这意味着如果它知道资产是缓存的,它甚至不会打扰请求它。
#Etags should be based on the file parameters only (default includes INode)
FileETag MTime Size
#Rewrite stuff
RewriteEngine On
#This sets the environment variable (is_versioned) when the URL query string
#looks like ?874353948543 or any string of digits
RewriteCond %{QUERY_STRING} ^[0-9]+$
RewriteRule ^(.*)$ $1 [env=is_versioned:true]
<Directory /deployed-rails-app/public/ >
Options -Indexes FollowSymLinks -MultiViews
AllowOverride None
Order allow,deny
allow from all
#For files, force the browser to rely on cache-control directives and
#Rails asset timestamps by removing Etags and Last-Modified dates
#For all assets that aren't stamped by rails, cache them for ~ 3 hours
Header set "Cache-Control" "max-age=10000"
Header unset Etag
Header unset "Last-Modified"
#For all assets that ARE stamped by rails, cache them for 30 days
Header set "Cache-Control" "max-age=2592000" env=is_versioned
</Directory>
我已经以这种方式设置我的生产服务器,现在返回访问者只执行一个请求(Get /),它返回动态内容并缓存所有资产(~40 - 50)。
答案 1 :(得分:6)
我认为你可以使用ENV ['RAILS_ASSET_ID']来改变缓存破坏资产ID。不幸的是,这适用于所有资产。
但是如果没有设置,它会使用资产的源修改时间。如果自上次使用该文件以来尚未修改该文件,则应该不会有问题。
如果资产ID在未更改时发生变化,可能是因为您的部署过程会改变修改时间,也许您可能会考虑调整它。
最后,您始终可以override rails_asset_id with your own custom method。
希望这有帮助。
答案 2 :(得分:0)