Кеширует ли Firefox JavaScript и использует его без запроса, если в пути есть строка запроса?

Я хотел бы добавить строку запроса в конец пути javascript, чтобы при каждом обновлении моего приложения до новой версии загружался javascript. До тех пор, пока строка запроса одинакова, я хочу, чтобы она продолжала использовать кэшированную версию без выполнения http-запроса, чтобы проверить, изменился ли скрипт.

Я делаю это в PHP, читая из тега CVS. Когда я создаю HTML для вывода, я читаю тег CVS и использую его для добавления в конец пути javascript, чтобы он создавал тег script, который выглядит следующим образом:

<script src="javascript/messages/shipments.js?TPRSAPPS-DEV2_090828145712237-BRANCH" type="text/javascript"></script>

Пока приложение не изменилось, тег останется прежним, и, следовательно, строка запроса также останется. Браузер должен кешировать JS и вообще не выполнять сетевой запрос, потому что дата истечения срока давна. Каждый раз, когда приложение обновляется, эта строка запроса будет меняться, и браузер должен загрузить ее.

Это прекрасно работает в IE8. Моя проблема с Firefox. Firefox кэширует файлы, но в следующий раз, когда я загружаю страницу, Firebug показывает ответ 304, указывающий, что он все еще выполнял сетевой запрос для файла, а затем обнаружил, что он не изменился.

Поэтому мой вопрос заключается в том, игнорирует ли firefox заголовок expires и кеш javascript при наличии строки запроса?

Связанный: что Firefox решает не кэшировать? Судя по всему, Rails делает нечто подобное. Но это не отвечает на мой вопрос.

Вот ответ, который я получаю обратно на этот файл:

https://appdev.prsx.net/~jhargett/PRSApps-Motorlog/javascript/menuReader.js?TPRSAPPS-DEV2_090828145712237-BRANCH-DIFFERENT

HTTP/1.1 304 Not Modified
Date: Mon, 03 Oct 2011 18:35:26 GMT
Server: Apache/2.2.3 (Red Hat)
Connection: close
Etag: "179010-3f8-49a9a74334200"
Vary: Accept-Encoding

Вкладка Cache в Firebug говорит:

Last Modified   Mon Oct 03 2011 13:35:26 GMT-0500 (Central Daylight Time)
Last Fetched    Mon Oct 03 2011 13:35:26 GMT-0500 (Central Daylight Time)
Expires Fri Oct 28 2011 18:33:31 GMT-0500 (Central Daylight Time)
Data Size   345
Fetch Count 12
Device  disk

4 ответа

Решение

Логика, которую использует Firefox, чтобы решить, делать ли условный GET с учетом кэшированного ответа, выглядит так:

  1. Если есть соответствующий заголовок Vary, выполните повторную проверку.
  2. Если предполагается, что этот запрос принудительно загружен из кэша, не выполнять повторную проверку.
  3. Если этот запрос имеет флаг "всегда проверять", выполните повторную проверку.
  4. Если этот запрос имеет флаг "никогда не проверять", то повторная проверка выполняется только в том случае, если это ответ без хранилища или ответ без кэширования SSL.
  5. Если код состояния ответа не может быть кэширован, или ответ не кэшируется или не хранится, или если срок действия истек до даты ответа, выполните повторную проверку.
  6. Если есть параметр запроса, а в ответе нет явного срока действия или максимального возраста, повторите проверку.
  7. Если время истечения ответа истекло, проведите повторную проверку (если не установлено "повторная проверка только один раз для каждого сеанса").

Таким образом, для вашего случая не должно быть условного GET, при условии, что вы на самом деле задали информацию об истечении срока действия или максимальном возрасте в ответе 200.

Тем не менее, некоторые из инструментов, которые пытаются отследить информацию HTTP для Firefox, фактически влияют на поведение повторной проверки, так что вы можете столкнуться с этим.

Я рекомендую создать журнал, следуя шагам в https://developer.mozilla.org/en/HTTP_Logging который, кстати, точно скажет вам, почему выполняется условное GET, если вы можете найти нужную часть журнала (поиск "nsHttpChannel::CheckCache enter"для регистрации из функции, которая реализует вышеупомянутую логику).

Если вы хотите быть абсолютно уверенным, что ваш файл будет перезагружен, лучше поместить строку номера версии / кеша прямо в имя файла. Так что у вас было бы что-то вроде shipments_v2.js или же shipments_(unix_timestamp).js, Это позаботится о прокси и любых других механизмах кэширования.

Как поясняется в ответе Бориса, одним из условий, запускающих условный запрос, является наличие заголовка Vary. Обычно вы не хотите удалять переменную в Accept-Encoding, но что вы можете сделать и что нужно сделать в случае, когда у вас есть управление версиями URL-адреса, - это оставить браузер без чего-либо для повторной проверки. В вашем случае это заголовок Etag. Это может быть также заголовок Last-Modified. Пример кода для лака, чтобы сделать это для вас, может выглядеть так:

  sub vcl_recv {
  [..]
        if (req.url ~ "\?v=\w+$") {
          set req.http.X-Versioned = "1";
        }
  [..]
  }

  sub vcl_deliver {
  [..]
        if (req.http.X-Versioned) {
          unset resp.http.Etag;
        }
  [..]
  }

То, на что вы смотрите, отличается от фактической загрузки файла, а затем говорит, что он не изменился.

Firefox делает HTTP-запрос для получения информации о файле, а не о самом файле. Это на самом деле означает, что Firefox делает это умнее, чем IE.

Запрос Firefox занимает всего пару байтов (размер файла, дата и т. Д.). поэтому независимо от имени Firefox кеширует его (если не отключено). Если сам файл изменяется, Firefox решает повторно загрузить файл.

То, на что вы указываете, на самом деле - правильное поведение.

Другие вопросы по тегам