- android - RelativeLayout 背景可绘制重叠内容
- android - 如何链接 cpufeatures lib 以获取 native android 库?
- java - OnItemClickListener 不起作用,但 OnLongItemClickListener 在自定义 ListView 中起作用
- java - Android 文件转字符串
在我的项目中,我尝试使用 HTML5 appcache 来缓存 CSS 和 JS 等静态资源,以及图像和视频等“用户特定”文件。当我说用户特定的图像/视频时,我试图为每个用户提供单独的文件,并且我还需要控制文件下载的顺序。
在这种情况下,我的 list 文件将为每个用户动态加载。有没有办法可以获取已缓存在客户端的资源列表?
如果没有,是否可以在客户端读取“.appcache”文件?
最佳答案
是的。您可以使用 AJAX 请求获取 list 缓存文件,然后读取它。
但是,这并不能保证问题中的浏览器具有可用的文件。
下面是示例代码
检查我们是否缓存了 HTML5 应用
如果我们未处于缓存状态,则计算 list 中加载的资源并根据 list 缓存条目计数(总计)显示进度条,并对所有 URL 执行手动 AJAX GET 请求以预热缓存。浏览器会自行执行此操作,但通过这种方式我们可以从流程中获取一些进度信息。
当缓存处于已知的良好状态时,继续前进
免责声明:自 2010 年以来未经过测试以工作
/**
* HTML5 offline manifest preloader.
*
* Load all manifest cached entries, so that they are immediately available during the web app execution.
* Display some nice JQuery progress while loading.
*
* @copyright 2010 mFabrik Research Oy
*
* @author Mikko Ohtamaa, http://opensourcehacker.com
*/
/**
* Preloader class constructor.
*
* Manifest is retrieved via HTTP GET and parsed.
* All cache entries are loaded using HTTP GET.
*
* Local storage attribute "preloaded" is used to check whether loading needs to be performed,
* as it is quite taxing operation.
*
* To debug this code and force retrieving of all manifest URLs, add reloaded=true HTTP GET query parameter:
*
*
*
* @param {Function} endCallback will be called when all offline entries are loaded
*
* @param {Object} progressMonitor ProgressMonitor object for which the status of the loading is reported.
*/
function Preloader(endCallback, progressMonitor, debug) {
if(!progressMonitor) {
throw "progressMonitor must be defined";
}
this.endCallback = endCallback;
this.progressMonitor = progressMonitor;
this.logging = debug; // Flag to control console.log() output
}
Preloader.prototype = {
/**
* Load HTML5 manifest and parse its data
*
* @param data: String, manifest file data
* @return Array of cache entries
*
* @throw: Exception if parsing fails
*/
parseManifest : function(data) {
/* Declare some helper string functions
*
* http://rickyrosario.com/blog/javascript-startswith-and-endswith-implementation-for-strings/
*
*/
function startswith(str, prefix) {
return str.indexOf(prefix) === 0;
}
var entries = [];
var sections = ["NETWORK", "CACHE", "FALLBACK"];
var currentSection = "CACHE";
var lines = data.split(/\r\n|\r|\n/);
var i;
if(lines.length <= 1) {
throw "Manifest does not contain text lines";
}
var firstLine = lines[0];
if(!(startswith(firstLine, "CACHE MANIFEST"))) {
throw "Invalid cache manifest header:" + firstLine;
}
for(i=1; i<lines.length; i++) {
var line = lines[i];
this.debug("Parsing line:" + line);
// If whitespace trimmed line is empty, skip it
line = jQuery.trim(line);
if(line == "") {
continue;
}
if(line[0] == "#") {
// skip comment;
continue;
}
// Test for a new section
var s = 0;
var sectionDetected = false;
for(s=0; s<sections.length; s++) {
var section = sections[s];
if(startswith(line, section + ":")) {
currentSection = section;
sectionDetected = true;
}
}
if(sectionDetected) {
continue;
}
// Otherwise assume we can check for cached url
if(currentSection == "CACHE") {
entries.push(line);
}
}
return entries;
},
/**
* Manifest is given as an <html> attribute.
*/
extractManifestURL : function() {
var url = $("html").attr("manifest");
if(url === null) {
alert("Preloader cannot find manifest URL from <html> tag");
return null;
}
return url;
},
isPreloaded : function() {
// May be null or false
return localStorage.getItem("preloaded") == true;
},
setPreloaded : function(status) {
localStorage.setItem("preloaded", status);
},
/**
* Check whether we need to purge offline cache.
*
*/
isForcedReload : function() {
// http://www.netlobo.com/url_query_string_javascript.html
function getQueryParam(name) {
name = name.replace(/[\[]/,"\\\[").replace(/[\]]/,"\\\]");
var regexS = "[\\?&]"+name+"=([^&#]*)";
var regex = new RegExp( regexS );
var results = regex.exec( window.location.href );
if (results == null) {
return "";
} else {
return results[1];
}
}
if(getQueryParam("reload") == "true") {
return true;
}
return false;
},
/**
* Do everything necessary to set-up offline application
*/
load : function() {
this.debug("Entering preloader");
if (window.applicationCache) {
this.debug("ApplicationCache status " + window.applicationCache.status);
this.debug("Please see http://www.w3.org/TR/html5/offline.html#applicationcache");
} else {
this.silentError("The browser does not support HTML5 applicationCache object");
return;
}
var cold;
if(this.isPreloaded()) {
// We have succesfully completed preloading before
// ...move forward
forceReload = this.isForcedReload();
if (forceReload == true) {
applicationCache.update();
} else {
this.endCallback();
return;
}
cold = false;
} else {
cold = true;
}
var url = this.extractManifestURL();
if(url === null) {
return;
}
this.progressMonitor.startProgress(cold);
$.get(url, {}, jQuery.proxy(manifestLoadedCallback, this));
function manifestLoadedCallback(data, textStatus, xhr) {
this.debug("Manifest retrieved");
var text = data;
manifestEntries = this.parseManifest(text);
this.debug("Parsed manifest entries:" + manifestEntries.length);
this.populateCache(manifestEntries);
}
},
/**
* Bootstrap async loading of cache entries.
*
* @param {Object} entrires
*/
populateCache : function(entries) {
this.manifestEntries = entries;
this.currentEntry = 0;
this.maxEntry = entries.length;
this.loadNextEntry();
},
/**
* Make AJAX request to next entry and update progress bar.
*
*/
loadNextEntry : function() {
if(this.currentEntry >= this.maxEntry) {
this.setPreloaded(true);
this.progressMonitor.endProgress();
this.endCallback();
}
var entryURL = this.manifestEntries[this.currentEntry];
this.debug("Loading entry: " + entryURL);
function done() {
this.currentEntry++;
this.progressMonitor.updateProgress(this.currentEntry, this.maxEntries);
this.loadNextEntry();
}
this.debug("Preloader fetching:" + entryURL + " (" + this.currentEntry + " / " + this.maxEntry + ")");
$.get(entryURL, {}, jQuery.proxy(done, this));
},
/**
* Write to debug console
*
* @param {String} msg
*/
debug : function(msg) {
if(this.logging) {
console.log(msg);
}
},
/**
* Non-end user visible error message
*
* @param {Object} msg
*/
silentError : function(msg) {
console.log(msg);
}
};
function ProgressMonitor() {
}
ProgressMonitor.prototype = {
/**
* Start progress bar... initialize as 0 / 0
*/
startProgress : function(coldVirgin) {
$("#web-app-loading-progress-monitor").show();
if(coldVirgin) {
$("#web-app-loading-progress-monitor .first-time").show();
}
},
endProgress : function() {
},
updateProgress : function(currentEntry, maxEntries) {
}
};
关于javascript - HTML5 appcache,获取客户端缓存文件列表,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9193528/
如果我包含在我的应用程序缓存 list 中: /example.html 这重定向到 https://s3.amazonaws.com/longURL/example.html?dynamicauth
本质上,我希望能够在我的网站上使用应用缓存文件,但仅限于移动设备,以使这些设备能够查看我正在离线开发的网站/网络应用程序,但是台式机/笔记本电脑通常可以访问互联网并且我宁愿这些人按原样查看网站,没有
情况 我正在构建一个网络应用程序,它将离线使用,但在线使用时也会定期更新。我通过添加包含 tstamp 的注释来使 list 服务器端无效,然后在检测到更改后立即通过 JS 自动重新加载页面。到目前为
通过提供 FALLBACK , 我期待 wifi.svg替换为 nowifi.svg当它从缓存中加载时。它没有按预期工作。 这是我的缓存 list 文件。 CACHE MANIFEST # Versi
我们试图弄清楚在前端 Controller 中启用 AppCache 对缓存有什么影响,而无需在响应对象上调用任何缓存指令。 我假设只需添加以下行并将 default_ttl 设置为 1: $kern
Service Worker和AppCache之间的核心区别是什么?每种方式的优缺点是什么,什么时候更喜欢一种方式。 最佳答案 主要区别在于AppCache是一个高级的声明性API,您可以使用它指
对于我的移动应用程序,我想使用 pushState 和 AppCache,但这似乎很棘手。 为了使 pushState 工作,我的网络服务器将每个 url( list 文件本身、图像、css 和 js
我有一个应用程序缓存(带有 NETWORK *)。所以现在我用 访问我的页面.然后页面本身像所有图像一样被缓存。但我希望页面自身不被缓存。我怎样才能做到这一点?我以为NETWORK *会成功的。 问
我的移动网络应用程序的主页是一个 .jsp 页面。我的应用程序需要登录(Google App Engine),因此当用户未登录时有一个登录按钮,当用户登录时有一个注销按钮,所有这些都由 .jsp 页面
我想使用应用缓存来离线查看我的应用,我想将其用作 CACHE MANIFEST CACHE: http://cdn.example.com/s/* NETWORK: * 浏览器有什么方法可以缓存“s”
我有一个检查我的 list 状态的页面 oad 事件,如果有变化,它会要求用户重新加载。但是,我正在尝试绑定(bind) 手动检查 noupdate 上是否有状态.我似乎无法让它工作,这是我的代码:
我正在开发一个 ipad 网络应用程序,它将接收每月的更改。但是我不知道如何让用户决定是否更新缓存。当 ipad 注意到 list 文件发生变化时,它往往会继续进行更新。我想防止这种情况发生,这样还没
在我的项目中,我尝试使用 HTML5 appcache 来缓存 CSS 和 JS 等静态资源,以及图像和视频等“用户特定”文件。当我说用户特定的图像/视频时,我试图为每个用户提供单独的文件,并且我还需
在我正在处理的整个 jQuery 移动网站中,我都有以下列方式引用 url 的 anchor 标记: "/目录/" "/目录/子目录/" 当然是指: “/目录/index.html” “/目录/子目录
我不明白 HTML5 AppCache 的意义。我们已经有了一个普通的缓存。如果您第一次访问网站,它会缓存所有 Assets 。 AppCache 提供了什么额外的值(value)?它只是一个文件列表
编辑:我不得不删除一些链接。 我的 list 页面似乎导致我的网页出现错误。当您第一次访问该页面时,一切似乎都已成功缓存,但刷新后却无法获取存在的文件。 我制作了一个快速测试页面以在此处查看。 这是我
我的应用程序目前正在使用 HTML5 appcache。 我想获取从 update() 事件中获取的文件的哈希值。但是,我似乎无法找到如何访问我下载的资源。 我想做类似的事情 $.get( "/sun
我最近添加了 Meteor appcache 包,因为我收到以下错误消息: ** You are using the appcache package but the total size of th
假设我有一个简单的应用程序缓存 list ,如下所示: CACHE: # v1 # images images/one.jpg images/two.jpg images/three.jpg 然后我使
我有一个使用 media queries based on pixel ratio 的网络应用程序向客户端设备提供适当分辨率的图像。例如,它将向 Windows 桌面传送 1x 图像,向具有视网膜显示
我是一名优秀的程序员,十分优秀!