在用sprockets 替换webpacker 的 Rails6 应用程序中,我没有设法让 sprockets 使我的浏览器缓存字体。编辑:我的浏览器确实缓存了字体,但谷歌抱怨并且 curl 显示了应用程序的响应方式(与304不同,见下文)。
更新
似乎304
只有当您告诉服务器(通过If-Modified-Since
-headers)您确切知道最后修改的版本时才会返回 a 。虽然我的 Mozilla 开发资源并没有说明这显然应该是这种情况(而且我没有阅读 RFC 的心情),但它可能是有道理的:
- 您的服务器在 2020 年 1 月 1 日为资产提供服务(为简单起见,批准日期)
- 浏览器访问您并将资产与日期一起存储
- 第二天同一浏览器重新访问,向服务器询问资产并告诉它最后一个已知日期(
2020-01-01
通过If-Modified-Since
-header)- 服务器回答
304
:你已经知道这些东西了
- 服务器回答
- 第二天发生错误,服务器提供开发资产
- 浏览器重新访问,获取新的(但错误的资产,
Last modified
日期为 2020-01-03)并将其存储在该日期旁边 - 服务器管理员删除了错误的开发资产
- 第二天,浏览器访问并告诉服务器“我知道昨天的事情”
- 服务器告诉浏览器:不,忘记了,正确的有效载荷是这个,这是时间戳:2020-01-01。
在下面的测试中,我使用If-Modified-Since
了与最后一个(生产)资产时间戳不对应的标题。感谢@bliof 帮助解决这个问题。
因为我的最终目标是让谷歌的速度洞察力快乐(现在我知道如果所有玩家都表现良好,这个 304- 响应有效)我将遵循 Rails 5+ 路径config.public_file_server.headers
(https://blog.bigbinary.com/2015/10 /31/rails-5-allows-setting-custom-http-headers-for-assets.html)。Rails 指南还指出了您通常如何让您的网络服务器(或 CDN)处理这种情况(https://guides.rubyonrails.org/asset_pipeline.html#in-production),但我的堆栈工作方式有所不同。
原文如下
字体在 eg 中app/assets/fonts/OTF/SourceSansPro-BoldIt.otf
并正确放入public/assets/OTF/...fingerprint...
(伴随着.gz变体)。它们通过 SCSS font-face 规则引用,指向其中包含相应指纹的文件(使用font-url()
)。
当curl
ing 这些时,我似乎永远不会得到 a HTTP/1.1 304 Not Modified
,而是 a200
与给定的有效载荷。使用其他(JS,CSS)资产,它可以按预期工作。
我没有修改config/initializers/assets.rb
,因为所有子目录和文件都应该已经被拾取(并且assets:precompile
输出和内容public/assets
显示它有效)。
深入了解https://github.com/rails/sprockets/blob/9909da64595ddcfa1e7ee40ed1d99738961288ec/lib/sprockets/server.rb#L73的 sprockets 代码似乎表明可能没有正确设置 etag 或类似的东西,但我确实这样做了并没有真正破坏该代码。
据我所知,该应用程序使用非常标准的 nginx 配置与 dokku(基本上是 heroku)一起部署:https ://github.com/dokku/dokku/blob/master/plugins/nginx-vhosts/templates/nginx .conf.sigil。该应用程序为资产本身提供服务(如在 heroku 中)。
我该怎么做才能使 sprockets 添加相关的标头/用 a “正确”响应304
?任何想法如何调试该问题?
相关的“调试”部分
对 CSS 的初始请求
curl -v https://...application-3d...c76c3.css \
-H 'Accept: text/css,*/*;q=0.1'\
-H 'Accept-Language: en-US,en;q=0.5'\
--compressed # omitted: ... User-Agent, DNT, ...
# omitted: TLS handshake etc
> GET /assets/application-3d...c76c3.css HTTP/1.1
> Host: #the host
> Accept-Encoding: deflate, gzip
> User-Agent: Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:75.0) Gecko/20100101 Firefox/75.0
> Accept: text/css,*/*;q=0.1
> Accept-Language: en-US,en;q=0.5
> Referer: #the host
> DNT: 1
> Connection: keep-alive
> Cookie: #a cookie
>
< HTTP/1.1 200 OK
< Server: nginx
< Date: Tue, 21 Apr 2020 15:39:47 GMT
< Content-Type: text/css
< Content-Length: 41256
< Connection: keep-alive
< Last-Modified: Mon, 06 Apr 2020 11:59:56 GMT
< Content-Encoding: gzip
< Vary: Accept-Encoding
<
# payload
后续获取 CSS
(相关部分,其他参数和输出省略)。请注意,会同时发送If-Modified-Since: Mon, 06 Apr 2020 11:59:56 GMT标头。
curl -v 'https://.../assets/application-3d...c76c3.css' \
-H 'If-Modified-Since: Mon, 06 Apr 2020 11:59:56 GMT'\
-H 'Cache-Control: max-age=0'
> If-Modified-Since: Mon, 06 Apr 2020 11:59:56 GMT
> Cache-Control: max-age=0
>
< HTTP/1.1 304 Not Modified
< Server: nginx
< Date: Tue, 21 Apr 2020 15:50:52 GMT
< Connection: keep-alive
(这就是我想要的:A 304 Not Modified。
字体资源的初始请求
curl -v 'https://.../assets/WOFF2/TTF/SourceSansPro-Light.ttf-32...d9.woff2' \
-H 'Accept: application/font-woff2;q=1.0,application/font-woff;q=0.9,*/*;q=0.8'\
-H 'Accept-Language: en-US,en;q=0.5'\
--compressed \
-H 'Referer: https://...assets/application-3d....c76c3.css'
# ommitted: User Agent, Cookies, ....
> GET /assets/WOFF2/TTF/SourceSansPro-Light.ttf-32...d9.woff2 HTTP/1.1
> Host: #the host
> Accept-Encoding: deflate, gzip
> User-Agent: Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:75.0) Gecko/20100101 Firefox/75.0
> Accept: application/font-woff2;q=1.0,application/font-woff;q=0.9,*/*;q=0.8
> Accept-Language: en-US,en;q=0.5
> DNT: 1
> Connection: keep-alive
> Referer: https://.../assets/application-3d...c76c3.css
# cookie etc
>
< HTTP/1.1 200 OK
< Server: nginx
< Date: Tue, 21 Apr 2020 15:45:34 GMT
< Content-Type: application/font-woff2
< Content-Length: 88732
< Connection: keep-alive
< Last-Modified: Wed, 25 Mar 2020 20:09:14 GMT
<
# payload
后续获取字体
curl -v 'https://.../assets/WOFF2/TTF/SourceSansPro-Light.ttf-32...ed9.woff2' \
-H 'Referer: https://.../assets/application-3d...c76c3.css'\
-H 'If-Modified-Since: Mon, 06 Apr 2020 11:59:56 GMT'
-H 'Cache-Control: max-age=0'
# ....
> If-Modified-Since: Mon, 06 Apr 2020 11:59:56 GMT
> Cache-Control: max-age=0
>
< HTTP/1.1 200 OK
< Server: nginx
< Date: Tue, 21 Apr 2020 15:53:46 GMT
< Content-Type: application/font-woff2
< Content-Length: 88732
< Connection: keep-alive
< Last-Modified: Wed, 25 Mar 2020 20:09:14 GMT
# payload
我发现有趣的是,服务器实际上发送了Last-Modified,它在If-Modified-Since之前。我猜聪明的浏览器会在那里停止对话,但我真的很想看到一个表现良好的 304。