Веб-приложение iOS — как бороться с чрезмерным кэшированием приложений?

Последний месяц я разрабатывал довольно сложное HTML5 веб-приложение. Прошлой ночью мой iPhone внезапно решил кэшировать все JS, CSS и изображения и не загружать обновленные копии. Это произошло и с iPhone моего партнера, поэтому я предполагаю, что это влияет на всех пользователей нашего приложения.

Излишне говорить, что очистка кеша браузера, удаление веб-приложения, перезагрузка телефона и перезапуск беспроводного соединения никак не решают проблему.

Удаление <meta name="apple-mobile-web-app-capable" content="yes"> решает проблему, но создает новую проблему, поскольку нам нужно, чтобы приложение работало как... приложение.

Мы также не собираемся добавлять старый трюк ?number в конец всех наших скриптов, таблиц стилей и изображений. Это просто смешно. Кроме того, если бы мы должны были реализовать что-то подобное, это должна была быть какая-то динамическая реализация JS. Наше приложение представляет собой одну HTML-страницу, которая загружает большинство скриптов, а дополнительные страницы подключаются через AJAX, дополнительные данные также получаются через AJAX. Я думаю, это можно сделать, но я надеюсь на более элегантное решение. Знаете, я чувствую, что мне не нужно ничего делать, так как все это работало без сучка и задоринки целый месяц.

Использование тегов cache-control, expires и pragma <meta> также не приносит нам никакой пользы, так как это чисто проблема веб-приложения iOS. Кэширование нормально работает в мобильном Safari, мобильном Chrome и во всех настольных браузерах. Похоже, что в iOS есть отдельный кеш для приложений, включая веб-приложения, которые пользователь не может очистить.

Кажется, что многие пользователи SO столкнулись с этой проблемой, но я не могу найти удовлетворительных решений. Кто-нибудь в похожей ситуации решал эту проблему? Могу ли я использовать файл манифеста, чтобы указать не для кэширования нескольких файлов? Похоже, что файлы манифеста используются для противоположного.


person Ben Y    schedule 10.07.2013    source источник
comment
подтверждено, что все еще является (огромной) проблемой в iOS7   -  person bart s    schedule 20.09.2013
comment
Используете ли вы кэш приложения HTML? Если нет, вы можете «обмануть» кеш веб-приложения iOS, заставив его сбрасывать кеш, создав манифест кеша приложения с файлами, которые необходимо обновить. Затем, когда вам нужно внести изменения и протестировать изменения, отключите манифест, изменив имя файла манифеста на вашем веб-сервере. Это делает недействительным сохраненный манифест и кэшированные файлы, поскольку манифест на сервере не может быть найден.   -  person BigMacAttack    schedule 20.09.2013
comment
Не используя кэш приложений и не используя манифест. Веб-приложение используется в «производственной» среде. Невозможно обновить нашу систему где-то в существующей установке и изменить имя файла, чтобы обмануть кеш. В моей среде разработки я могу легко добавить некоторое число к имени файла для тестирования, но, как говорит ОП, в производственной среде об этом не может быть и речи.   -  person bart s    schedule 23.09.2013
comment
У меня тоже было это, если я открываю URL-адрес в Safari, он загружает последнюю версию JS. Как только я добавляю его на главный экран в качестве веб-приложения, он снова начинает использовать старый JS. Ужасный.   -  person Adam Marshall    schedule 02.01.2014


Ответы (1)


Как бы то ни было, и это не идеальное решение, нам пришлось довольствоваться добавлением строк запроса. Я написал сценарий оболочки, чтобы сделать эту и несколько других задач немного более автоматизированными, вы можете посмотреть исходный код на Гитхаб. Несколько деталей:

  • Он разработан для JS, но его можно легко отредактировать и для работы с CSS.
  • Он берет все файлы, перечисленные в script_order.txt, и компилирует их с помощью Google Closure Compiler.
  • По возможности группирует их в фрагменты размером менее 25 КБ (iPhone не будет кэшировать ничего более 25 КБ до gzip, хотя, по-видимому, это распространяется только на браузеры, а не на отдельные веб-приложения)
  • Выводит файл PHP с тегами <script>, к именам файлов скриптов которых добавлено ?v=timestamp. Если вы работаете со статическим HTML и не можете включить файл PHP, вы можете переписать вывод, чтобы добавить теги script в файл index.html.

Другим довольно хакерским решением было бы сохранить ваш JS/CSS с расширением файла .php, и в этих файлах установить заголовки примерно так:

<?php
header("content-type: application/javascript");
header('Cache-Control: no-cache');
header('Pragma: no-cache');
?>
window.alert('hello world');

ИЗМЕНИТЬ:

Установка даты на 2, 3 или 4 дня в будущем, запуск приложения с домашнего экрана, а затем установка даты обратно в нормальное состояние также могут помочь.

person Ben Y    schedule 22.09.2013
comment
Вы уверены, что ваш ответ имеет какое-то отношение к вопросу? Я не знаю для OP, но у меня нет веб-сервера PHP. Временные метки могут быть легко добавлены к именам файлов с помощью javascript. Вопрос ясно говорит We're not going to go around appending the old trick ?number to the end of all our scripts, stylesheets, and images either. That's ridiculous. - person bart s; 23.09.2013
comment
@bart-s Я являюсь оператором. Как я уже сказал, нам пришлось остановиться на строке запроса, хотя я этого не хотел. Конечно, с помощью JS легко добавить временные метки, но сценарий оболочки может, по крайней мере, помочь автоматизировать процесс развертывания во многих системах разработки и промежуточных/производственных средах. PHP здесь не нужен. Просто выкладываю свое решение на случай, если вы сможете выбрать из него полезные части, но, видимо, это было не так. Поверь мне, я чувствую твою боль. - person Ben Y; 23.09.2013
comment
Я, должно быть, упустил из виду, что ты ОП. Кэширование смешное. Даже если у вас все в порядке в браузере, при сохранении на домашний экран данные все равно будут из кеша. Я нашел еще один трюк, устанавливающий дату в будущем. Добавлено к вашему ответу, чтобы позволить мне удалить -1 - person bart s; 23.09.2013
comment
Не беспокойся, чувак. Это действительно позор — мы не должны прибегать к хитроумным обходным путям, чтобы заставить что-то настолько стандартное работать на таком стандартном устройстве. Спасибо, что поделились своим трюком, я собираюсь попробовать. - person Ben Y; 23.09.2013
comment
Установка даты на будущее, а затем обратно сработала для меня, спасибо, bart s :) - person Adam Marshall; 02.01.2014
comment
Обратите внимание, что трюк с датами может быть удобен при разработке, но он не поможет вашим пользователям, если вы не ожидаете, что они сами проделают этот трюк. - person Ben Y; 03.01.2014