Автономное приложение HTML5 всегда отправляет событие ошибки на iPod Touch iOS 4.2.1

У меня проблема в iOS с автономным приложением HTML5. Мое приложение отлично работает в автономном режиме в Firefox, Chrome и Android 2.2, но не на моем iPod Touch под управлением iOS 4.2.1.

Вот мой манифест (JSP) под названием «1.cache.manifest.jsp». Я использую JSP «no-cache.jsp», чтобы спросить, не кэшируется ли манифест. Я также добавляю в манифест «index.jsp», хотя это совершенно не обязательно, так как это ресурс, который ссылается на манифест.

<%@page contentType="text/cache-manifest; charset=UTF-8" pageEncoding="UTF-8"
%><jsp:include page="no-cache.jsp" flush="true"
/><%
String cacheManifestVersion = "20110220 1224";
//System.out.println("Cache manifest version=" + cacheManifestVersion);
%>CACHE MANIFEST
index.jsp
cache-this.js.jsp

Вот моя страница index.jsp. Он прослушивает события applicationCache и выводит тип события. Я использую JSP "no-cache.jsp", чтобы попросить, чтобы HTML не кэшировался.

<%@page contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"
%><jsp:include page="no-cache.jsp" flush="true"
/><!DOCTYPE html>
<html manifest="1.cache.manifest.jsp">
<head>
<script>
var appCacheEvents = ["checking", "error", "noupdate", "downloading", "progress", "updateready", "cached", "obsolete"];

for (var i = 0; i < appCacheEvents.length; i++) {
    applicationCache.addEventListener(appCacheEvents[i], function (evt) {
        var el = document.getElementById("applicationCache-events");
        el.innerHTML += "applicationCache " + evt.type + " event.<br/>";
    }, false);
}
</script>
<script src="./cache-this.js.jsp"></script>
</head>
<body>
<div id="applicationCache-events"></div>
<div id="cache-this-output"></div>
</body>
</html>

«cache-this.js.jsp» — это некоторый javascript, который добавляет некоторый текст на страницу при загрузке:

<%@page contentType="application/javascript; charset=UTF-8" pageEncoding="UTF-8"
%><jsp:include page="no-cache.jsp" flush="true"
/>// cache this
window.addEventListener("load", function (evt) {
    var msg = "Script loaded " + new Date();
    document.getElementById("cache-this-output").innerHTML = msg;
}, false);

Это вывод для тех пользовательских агентов, которые работают при ПЕРВОМ доступе к сайту:

applicationCache checking event.
applicationCache downloading event.
applicationCache progress event.
applicationCache progress event.
applicationCache cached event.
Script loaded Sun Feb 20 2011 13:22:33 GMT+0000 (GMT Standard Time)

Впоследствии вывод:

applicationCache checking event.
applicationCache noupdate event.
Script loaded Sun Feb 20 2011 13:23:47 GMT+0000 (GMT Standard Time)

И в автономном режиме (в Firefox) я получаю следующее. Обратите внимание на событие «ошибка», но приложение ДЕЙСТВИТЕЛЬНО работает в автономном режиме (даже после очистки кэша HTTP).

applicationCache checking event.
applicationCache error event.
Script loaded Sun Feb 20 2011 13:26:54 GMT+0000 (GMT Standard Time)

На моем iPod Touch я получаю тот же результат (как при первом доступе), ЗА ИСКЛЮЧЕНИЕМ, что «кэшированное» событие заменяется событием «ошибка».

Есть идеи, почему iOS изначально не может кэшировать приложение?


person Paul Grime    schedule 22.02.2011    source источник
comment
Не совсем по теме, но я надеюсь, что это поможет кому-то. У меня были похожие симптомы, но с https и только в качестве веб-приложения на домашнем экране — элементы кеша загружались один раз, любые последующие проверки файла манифеста кеша выдавали сообщение об ошибке после добавления предлагаемых обработчиков событий. После нескольких дней устранения неполадок выяснилось, что вся проблема заключалась в том, что я использовал ненадежный сертификат ssl для тестирования. Когда я заменил его действительным сертификатом ssl, проблема исчезла.   -  person    schedule 29.06.2011


Ответы (2)


Можете ли вы увидеть, что ваш статус возвращается, когда вы получаете свои ошибки? Вот аналогичная функция, которую я использую, которая возвращает несколько дополнительных переменных, которые могут помочь вам устранить неполадки с вашей стороны:

var cacheStatusValues = [];
cacheStatusValues[0] = 'uncached';
cacheStatusValues[1] = 'idle';
cacheStatusValues[2] = 'checking';
cacheStatusValues[3] = 'downloading';
cacheStatusValues[4] = 'updateready';
cacheStatusValues[5] = 'obsolete';

var cache = window.applicationCache;
cache.addEventListener('cached', logEvent, false);
cache.addEventListener('checking', logEvent, false);
cache.addEventListener('downloading', logEvent, false);
cache.addEventListener('error', logEvent, false);
cache.addEventListener('noupdate', logEvent, false);
cache.addEventListener('obsolete', logEvent, false);
cache.addEventListener('progress', logEvent, false);
cache.addEventListener('updateready', logEvent, false);

function logEvent(e) {
    var online, status, type, message;
    online = (navigator.onLine) ? 'yes' : 'no';
    status = cacheStatusValues[cache.status];
    type = e.type;
    message = 'online: ' + online;
    message+= ', event: ' + type;
    message+= ', status: ' + status;
    if (type == 'error' && navigator.onLine) {
        message+= ' (prolly a syntax error in manifest)';
    }
    console.log(message);
}

window.applicationCache.addEventListener(
    'updateready', 
    function(){
        window.applicationCache.swapCache();
        console.log('swap cache has been called');
    }, 
    false
);
person TNC    schedule 22.02.2011
comment
У меня такая же проблема. На самом деле, регистрация подобных сообщений даже недоступна в iOS. Поэтому я не знаю, как вы планируете использовать этот метод отладки на iPhone и iPad. Кажется, что функция манифеста кеша полностью не работает в iOS. Иначе как вы объясните, что мое приложение отлично работает в автономном режиме на моем рабочем столе, но не работает на iPad?? - person IgorGanapolsky; 04.04.2011
comment
Это неправильно. Он полностью функционален в iOS, просто не в вашем устройстве, поскольку вы используете его, как и все остальные (это сделано специально). Вы можете очень легко регистрировать/отлаживать с помощью симулятора/xcode. С точки зрения того, почему ваше приложение работает или работает правильно, зависит от вас. Но это было создано для HTML5 и полностью поддерживается веб-китом/iOS. - person TNC; 04.04.2011
comment
В этом случае я не понимаю, почему мобильное сафари даже не запрашивает cache.manifest. Я просматриваю журналы своего сервера, и настольный браузер делает запрос cache.manifest, но мобильное сафари на iPad и iOS Simulator этого не делает! - person IgorGanapolsky; 04.04.2011

Я использую это, чтобы увидеть результаты ошибок на Ipad, iPhone или iPod Touch.

var bubbleTimeout;
var verboseMessage = true;

function initCache() {

if ( webappCache != null ) {
    // create event listeners for all associated events
    webappCache.addEventListener('cached', showSave, false);
    webappCache.addEventListener('downloading', showWaiting, false);
    webappCache.addEventListener('error', errorHandler, false);
    webappCache.addEventListener('updateready', updateReady, false);
    webappCache.addEventListener('noupdate', updateReady, false);
    webappCache.addEventListener('progress', showWaiting, false);
    webappCache.addEventListener('checking', showWaiting, false);
    }
}

function errorHandler(e) {

  if ( verboseMessage ) {
    newBubble("phase :"+e.eventPhase+" \n"+
      "currentTarget: "+e.currentTarget+"\n"+
      "target: "+e.target+"\n"+
      "type: "+e.type+"\n"+
      "cancelable: "+e.cancelable+"\n"+
      "bubbles: "+e.bubbles+"\n"+
      "cancelBubble: "+e.cancelBubble+"\n"+
      "message: "+e.message+"\n"
     );
} else {
    // newBubble("Connection Error, prolly bad manifest", false);
   }
}

function newBubble( textMsg, showButton ) {

if ( bubbleTimeout ) {
    clearTimeout(bubbleTimeout);
}

if ( showButton ) textMsg += "<br /><button type='button' onclick='hideBubble()'>OK</button>";

if ( !document.getElementById("bubble") ) {

    var divTag = document.createElement("div");
    divTag.id = "bubble";
    divTag.className ="bubble";
    document.getElementById("theFrame").appendChild(divTag);
    divTag.innerHTML = textMsg;
    divTag.style.visibility = "visible";

} else {

    document.getElementById("bubble").innerHTML = textMsg;
    document.getElementById("bubble").style.visibility = "visible";
}

bubbleTimeout = setTimeout("hideBubble()",15000);   
}

function hideBubble() {

$('#bubble').css('visibility','hidden');
}
person Jimmy Moffitt    schedule 21.06.2011