Как динамически обслуживать манифест для перестановок GWT
Рассмотрим следующую задачу. Вы хотите предоставить автономный файл манифеста / appcache для вашего проекта GWT. В таком случае возникает два вопроса:
- GWT генерирует различные перестановки файлов js (в зависимости от версии браузера). При загрузке приложения, некоторые GWT javascript-код использует ваши свойства агента пользователя, чтобы включить соответствующий. Вы захотите создать отдельный файл манифеста для каждой из этих перестановок, так как вы не хотите кэшировать файлы, которые вы не будете используйте (и эти файлы могут быть около 0,5 мб на перестановку). Эта проблема рассматривается компоновщиком Манифеста MGWT , который генерирует различные файлы манифеста в процессе компиляции
- обслуживание соответствующего файла манифеста при загрузке веб-приложения в браузере
Этот вопрос относится к вопросу 2. Как мы можем служить этому манифесту динамично, надежно? MGWT использует сервлет , который обслуживает манифест, в зависимости от агента пользователя из запроса.
Вам нужно будет сопоставить строку агента пользователя (например, Mozilla/4.0 (compatible; MSIE 6.0b; Windows NT 5.1)
) с идентификатором агента пользователя (например, ie6
). Используя файл сопоставления, созданный компоновщиком MGWT, вы можете найти файл манифеста для обслуживания клиента. Основным недостатком является то, что вам нужно будет выполнить несколько простых строковых операций, чтобы сопоставить полную строку агента пользователя с этим идентификатором агента пользователя с некоторым наивным соответствием строк. Вы не сможете повторно использовать клиентский GWT-код для такого сопоставления. (все это обсуждается в этой теме ). Как в результате, всякий раз, когда GWT получает обновление, которое изменяет количество перестановок и/или поддерживаемых браузеров, вам также нужно изменить код сервлета. Другими словами: это не надежное решение.
Вопрос заключается в следующем: можем ли мы обслуживать манифест по-другому для этих перестановок GWT, обслуживая эти файлы динамически на стороне клиента?
2 ответа:
Да, однако окольным путем. Это не возможно, чтобы динамически изменить атрибут HTML-код "проявляется" через JavaScript. Обходным путем является создание iframe с помощью javascript, который ссылается на пустую html-страницу с определенным атрибутом манифеста в ней (см. Этот раздел). Чтобы это работало в GWT, вам нужно:
Измените компоновщик MGWT, поэтому для каждой перестановки вы создадите пустую html-страницу со ссылкой на этот манифест перестановок. Что-то например:
toReturn.add(emitString( logger, "<html manifest=\"" + permutation + ".manifest\"><head></head><body></body></html>", permutation + ".manifest.html") );
В коде клиента GWT при загрузке модуля: извлеките строгое имя перестановки и используйте его для вставки iframe для этой перестановки. Это будет выглядеть так:
В вашем классе ввода:
public void onModuleLoad() { appendManifestIframe(GWT.getPermutationStrongName() + ".manifest.html"); } public static native void appendManifestIframe(String manifestIframe) /*-{ var ifrm = document.createElement("iframe"); ifrm.setAttribute("src", manifestIframe); ifrm.style.width = 0+"px"; ifrm.style.height = 0+"px"; $doc.body.appendChild(ifrm); }-*/;
Обратите внимание, что
GWT.getPermutationStrongName
возвращает 'HostedMode', когда вы находитесь в режиме dev. То есть, вы не сможете использовать этот подход в режиме dev (или вы должны убедиться, что вы пишете отдельный манифест/iframe дляHostedMode
)
Я не уверен в подходе вычисления файла манифеста для использования на стороне клиента. Позвольте мне объяснить:
Атрибут manifest сообщает браузеру, что эта страница и все ресурсы, включенные в манифест и используемые этой страницей, должны быть кэшированы и получены из кэша.
, Если вы не задаете атрибут манифеста в индексе.html, страница не будет кэшироваться и не будет использовать никаких ресурсов из кэша.
Используя подход iframe, вы бы загрузили фрейм.html с набором атрибутов манифеста, и этот манифест будет включать индекс.html и все его активы.
Я этого не тестировал, но думаю, что хотя бы браузер кешировал и получал индекс.html из автономного хранилища, он не получит никакого актива, включенного в него с момента индексирования.html не имеет набора атрибутов манифеста, поэтому ваш модуль.nocache.js никогда не будет загружен, если устройство находится в автономном режиме.