如何为GWT排列动态提供清单

时间:2013-09-10 14:40:55

标签: html5 gwt offline-caching mgwt

考虑以下问题。您想为GWT项目提供脱机清单/ appcache文件。在这种情况下,有两个问题:

  1. GWT生成js文件的不同排列(取决于浏览器版本)。加载应用程序时,某些GWT javascript代码使用您的用户代理属性来包含相应的属性。您需要为每个排列生成不同的清单文件,因为您不希望缓存不使用的文件(这些文件每个排列大约为0.5MB)。 MGWT Manifest Linker涵盖了此问题,它在编译过程中生成不同的清单文件
  2. 在浏览器中加载网络应用程序时提供相应的清单文件
  3. 这个问题与问题2有关。我们如何以健壮的方式动态地提供此清单? MGWT使用servlet来提供清单,具体取决于请求中的用户代理。 您需要将用户代理字符串(例如Mozilla/4.0 (compatible; MSIE 6.0b; Windows NT 5.1))映射到“用户代理ID”(例如ie6)。使用MGWT链接器创建的映射文件,您可以找到要提供给客户端的清单文件。一个主要的缺点是你需要做一些简单的字符串操作,用一些天真的字符串匹配将完整的用户代理字符串映射到这个用户代理id。您将无法重新使用客户端GWT代码进行此类映射。 (这在this topic中讨论过)。因此,每当GWT收到更改更改排列数量和/或支持的浏览器的更新时,您也需要更改您的servlet代码。换句话说:这不是一个强有力的解决方案。

    问题是:我们可以通过在客户端动态提供这些文件,以不同的方式为这些GWT排列提供清单吗?

2 个答案:

答案 0 :(得分:1)

是的,但是以一种圆桌的方式。无法通过javascript动态更改html'manifest'属性。解决方法是通过javascript生成iframe,它引用一个带有特定清单属性的空html页面(请参阅this topic)。为了在GWT中工作,您需要:

  1. 更改MGWT链接器,因此对于每个排列,您将创建一个空的html页面,其中引用了此排列清单。类似的东西:

    toReturn.add(emitString(
            logger, 
            "<html manifest=\"" + permutation + ".manifest\"><head></head><body></body></html>", 
            permutation + ".manifest.html")
    );
    
  2. 在您的GWT客户端代码中,在模块加载时:检索您的排列强名称,并使用此插入iframe进行此排列。这看起来像这样:

  3. 在您的入门课程中:

    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”。即,您将无法在开发模式下使用此方法(或者您应该确保为HostedMode编写separete清单/ iframe)

答案 1 :(得分:0)

对于在客户端计算要使用的清单文件的方法,我并不乐观。让我解释一下:

manifest属性告诉浏览器该页面以及清单中包含的所有资产以及此页面使用的所有资产都必须缓存并从缓存中获取。

如果您未在index.html中设置清单属性,则不会缓存该页面,也不会使用缓存中的任何资源。

使用iframe方法,您将加载一个设置了manifest属性的iframe.html,此清单将包含index.html及其所有资产。

我没有对此进行测试,但我认为虽然浏览器会缓存并从离线存储中获取index.html,但由于index.html没有设置manifest属性,因此不会包含任何资产。所以如果设备离线,你的module.nocache.js永远不会被加载。