Как заставить звездочки (или стойки, или nginx?) Заставить браузеры кэшировать шрифты и правильно возвращать 304? - PullRequest
2 голосов
/ 20 апреля 2020

В приложении Rails6 с заменой webpacker на звездочки мне не удается позволить звездочкам создавать шрифты кэша моего браузера. Редактировать: мой браузер кэширует шрифт, но Google жалуется, и скручиваемость показывает, как приложение реагирует (не так, как ожидалось с 304 , см. Ниже).

Обновление

Кажется, что 304 возвращается только тогда, когда вы сообщаете серверу (через If-Modified-Since -headers), что вам точно известна последняя измененная версия. Хотя I Mozillas Dev Resources не заявляет, что это должно быть именно так (и я не нахожусь в настроении чтения RF C), это может иметь смысл:

  • ваш сервер обслуживает ресурс на 2020-01-01 (назначенная дата для простоты)
  • браузер посещает вас и сохраняет актив вместе с его датой
  • на следующий день тот же браузер повторно посещает сервер, запрашивает у сервера актив и сообщает ему последний известный дата (2020-01-01 через If-Modified-Since -header)
    • сервер отвечает 304: Вы уже знаете, что материал
  • на следующий день происходит ошибка, и разработчик ресурс обслуживается сервером
  • , проверяет браузер, получает новый (но неверный ресурс с Last modified дата 2020-01-03) и сохраняет его вместе с этой датой
  • администраторы сервера удаляют неправильные dev asset
  • на следующий день браузер заходит и сообщает серверу "Я знаю, что было вчера"
    • сервер сообщает браузеру: нет, забыл, правильная полезная нагрузка - это, и это временная метка : 2020-01-01.

В моих тестах ниже я использовал If-Modified-Since заголовки, которые не соответствовали последней (производственной) метке времени актива. Спасибо @bliof за помощь в выяснении этого.

Поскольку моей конечной целью было сделать понимание скорости googles счастливым (теперь, когда я знаю, что этот 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 -производство ), но мой стек работает несколько иначе.

Далее следует

Шрифты, например, app/assets/fonts/OTF/SourceSansPro-BoldIt.otf и правильно вставлены public/assets/OTF/...fingerprint... (сопровождается вариантом .gz ). На них ссылаются с помощью правила шрифта S CSS, указывающего на файл с соответствующим отпечатком пальца (используя font-url()).

При curl этом я, кажется, никогда не получаю HTTP/1.1 304 Not Modified, но 200 с заданной полезной нагрузкой. С другими активами (JS, CSS) он работает как положено.

Я не изменил config/initializers/assets.rb, так как все подкаталоги и файлы уже должны быть подобраны (и вывод assets:precompile) и содержание public/assets показывает, что оно работает).

Копание кода звездочек в https://github.com/rails/sprockets/blob/9909da64595ddcfa1e7ee40ed1d99738961288ec/lib/sprockets/server.rb#L73, кажется, указывает на то, что, возможно, etag установлен неправильно или что-то в этом роде, но Я на самом деле не взламываю этот код.

Приложение развернуто с помощью dokku (в основном, heroku) с довольно стандартной nginx -конфигурацией, насколько я могу судить: https://github.com/dokku/dokku/blob/master/plugins/nginx-vhosts/templates/nginx.conf.sigil , Приложение обслуживает сами ресурсы (как в heroku).

Что мне нужно сделать, чтобы звездочки добавляли соответствующие заголовки / отвечали "правильно" с 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 Не изменено .

Первоначальный запрос на шрифт

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 с хорошим поведением.

1 Ответ

1 голос
/ 24 апреля 2020

Вот несколько заметок / выводов:


Кажется, что он возвращает 304, когда вы сопоставляете отметку времени.

В вашем примере, если вы свернете шрифт с помощью

-H 'If-Modified-Since: Wed, 25 Mar 2020 20:09:14 GMT'

Вы получите HTTP/1.1 304 Not Modified

То же самое для .css, если вы не точно соответствуете дате, вы получите 200.


Я попытался изменить звездочки локально, чтобы добавить некоторые вызовы puts, а также изменить уровень журнала по умолчанию для самих звездочек, но ничего не происходит.

TBO Я не верю, что Sprokets :: Server Вызов #call.


Я пробовал с puma и thin, оба возвращают 304 только при совпадении дат.


curl --compressed -H 'Cache-Control: max-age=0' -H 'If-Modified-Since: Thu, 23 Apr 2020 21:34:30 GMT' -v http://localhost:3000/assets/OTF/SpaceMeatball-d61519ff17fadd38b57e3698067894c0e75fcb6031ee91034f5f7d6f2daa4d4b.otf

> Cache-Control: max-age=0
> If-Modified-Since: Thu, 23 Apr 2020 21:34:30 GMT
>
< HTTP/1.1 200 OK
< Last-Modified: Thu, 23 Apr 2020 21:34:29 GMT

curl --compressed -H 'Cache-Control: max-age=0' -H 'If-Modified-Since: Thu, 23 Apr 2020 21:34:29 GMT' -v http://localhost:3000/assets/OTF/SpaceMeatball-d61519ff17fadd38b57e3698067894c0e75fcb6031ee91034f5f7d6f2daa4d4b.otf

> Cache-Control: max-age=0
> If-Modified-Since: Thu, 23 Apr 2020 21:34:29 GMT
>
< HTTP/1.1 304 Not Modified

Я бегу рельсы, как это:

RAILS_SERVE_STATIC_FILES=1 RAILS_ENV=production ./bin/rails s
or 
RAILS_SERVE_STATIC_FILES=1 RAILS_ENV=production bundle exec thin start

todo - найти, что именно возвращает ответ :)

...