支持web应用程序时,未在iOS设备上缓存GWT应用程序置换脚本
最近,当我在iOS 6.x设备上以web app(全屏)模式运行时,我发现了一个与GWT应用中的缓存相关的问题。问题是,iOS似乎忽略了我对庞大排列文件的缓存策略指令(支持web应用程序时,未在iOS设备上缓存GWT应用程序置换脚本,gwt,web-applications,ios6,linker,cache-manifest,Gwt,Web Applications,Ios6,Linker,Cache Manifest,最近,当我在iOS 6.x设备上以web app(全屏)模式运行时,我发现了一个与GWT应用中的缓存相关的问题。问题是,iOS似乎忽略了我对庞大排列文件的缓存策略指令(.cache.html) 我有一个servlet过滤器设置静态资源上的缓存头,包括*.cache.html文件,例如: # Response header snippet Expires: Fri, 26 Jul 2013 09:58:28 GMT Cache-Control: public, max-age=8640000 ET
.cache.html
)
我有一个servlet过滤器设置静态资源上的缓存头,包括*.cache.html
文件,例如:
# Response header snippet
Expires: Fri, 26 Jul 2013 09:58:28 GMT
Cache-Control: public, max-age=8640000
ETag: W/"322107-1359629388000"
Last-Modified: Thu, 31 Jan 2013 10:49:48 GMT
但是,一旦我加入web应用程序支持并将应用程序添加到我的主屏幕,iOS设备将在每次加载时请求排列文件,如果不匹配,则不发送,如果自请求头修改,则不发送。通过
标记添加Web应用程序支持:
我在任何地方都找不到这个问题的文档,也不确定它是否是一个bug。然而,这正是我所经历的。缓存在我的桌面浏览器中按预期工作,在那里我可以检查收到的标题。我在任何地方都无法嗅探用户代理并根据此信息进行区分,以便所有客户端都将收到相同的头
我能够通过一个HTML5缓存清单文件“解决”眼前的问题,如本文所示,其中自定义生成一个清单文件,其中包含所有生成的排列,例如:
缓存清单
.cache.html
.cache.html
...
.cache.html
并将清单直接添加到主机页(.html
):
...
这一切都很好,除了现在所有的客户都会,即使只需要一个!我的案例是18个排列,每个排列在3G或Edge上~5MB:(这真的是最好的解决方案吗?我最后做的是进一步调查,发现不是在主机页中添加清单引用,而是可以将其添加到所有排列脚本中。清单本身可以是通用的(实际上是空的)文件:
我们鼓励作者也将主页包含在清单中,但实际上,引用清单的页面会自动缓存,即使没有明确提及。()
因此,我编写了一个简单的链接器
:
创建脱机清单文件
向所有置换脚本(*.cache.html
)的
标记添加清单
属性
链接器
称为ManifestLinker
,非常简单:
package com.example.linker;
//进口
@LinkerOrder(Order.POST)
公共类ManifestLinker扩展了AbstractLinker{
私有静态最终字符串MANIFEST\u FILE=“MANIFEST.nocache.appcache”;
私有静态最终字符串HTML_FIND=“”;
私有静态最终字符串HTML_REPLACE=“”;
/*(非Javadoc)
*@see com.google.gwt.core.ext.Linker#getDescription()
*/
@凌驾
公共字符串getDescription(){
return“`Manifest Linker`:添加对静态`cache.html`资源的AppCache支持。”;
}
@凌驾
公共工件集链接(TreeLogger、LinkerContext上下文、工件集工件)引发UnableToCompleteException{
工件集输出=新工件集(工件);
add(buildManifest(logger));
for(EmittedArtifact工件:artifacts.find(EmittedArtifact.class)){
if(artifact.getVisibility()==Visibility.Public&&artifact.getPartialPath().endsWith(“.cache.html”)){
logger.log(TreeLogger.TRACE,“处理文件:”+artifact.getPartialPath());
字符串cacheHtml=Util.readStreamAsString(artifact.getContents(logger));
if(cacheHtml.startsWith(HTML_FIND)){
cacheHtml=HTML\u REPLACE+cacheHtml.substring(HTML\u FIND.length());//REPLACE``标记。
replace(copyArtifact(logger、artifact、cacheHtml));
}
}
}
logger.log(TreeLogger.INFO,“已成功创建并链接清单”);
返回输出;
}
私有EmittedArtifact copyArtifact(TreeLogger、EmittedArtifact原件、字符串内容)引发UnableToCompleteException{
EmittedArtifact copy=emitString(记录器,目录,original.getPartialPath());
copy.setVisibility(original.getVisibility());
返回副本;
}
私有EmittedArtifactBuildManifest(TreeLogger记录器)引发UnableToCompleteException{
StringBuilder=新的StringBuilder();
builder.append(“缓存清单\n”)
.append(“#生成人”)
.append(getClass().getSimpleName())
.附加(“:”)
.append(System.currentTimeMillis())
.append(“.\n\n”)
.append(“网络:\n”)
.append(“*\n”);
SyntheticArtifactManifest=emitString(记录器,builder.toString(),清单文件);
返回舱单;
}
}
在我的.gwt.xml
文件中,我定义并添加链接器:
...
...
此外,我还确保通过我的web.xml
设置了正确的内容类型:
。。。
应用缓存
文本/缓存清单
...
发出的manifest.nocache.appcache
也很简单:
CACHE MANIFEST
# Generated by ManifestLinker: 1366702621298.
NETWORK:
*
CACHE MANIFEST
# Generated by ManifestLinker: 1366702621298.
NETWORK:
*