If you’ve built a hybrid app using WebView, Cordova, Capacitor or any HTML5-based stack, you’ve probably enabled AppCache or its modern cousin Service Workers to make your app work offline. Everything looks great until you try to programmatically read the contents of a cached file, like a .js
resource stored by AppCache.
You expect something simple like an AJAX call to return the content. Instead, it just refuses.
I’ll explain exactly why you can’t directly access AppCache files, how Objective-C, Java and JavaScript each behave in this case, and more importantly, how to solve it the right way, without banging your head against outdated browser internals.
Why Does AppCache Refuse to Give Me My Own File
AppCache was designed for loading, not reading.
When a file is cached by AppCache, it sits inside a protected browser cache location. It’s invisible to your JavaScript, Objective-C, and Java code. Your code cannot access it like a normal local file.
Here’s the failed experiment most developers try:
$.ajax({
url: "/abcweb/js/abc.scripts.min.js",
dataType: "script",
success: function(data){
alert(data);
}
});
Why? Because:
Request Method | Online | Offline | Can Access AppCache File? |
---|---|---|---|
<script src=""> | ✅ | ✅ | Yes |
AJAX (XMLHttpRequest ) | ✅ | ❌ | No — It triggers network logic |
The AppCache system will only serve cached files when requested via traditional HTML loading, not via fetch/XHR calls.
The string content://cz.mobilesoft.appblock.fileprovider/cache/blank.html
represents a Content URI on an Android device.
Here’s a breakdown of its components:
content://
: This is the standard scheme for Content URIs in Android, indicating that the URI refers to data managed by a Content Provider.cz.mobilesoft.appblock.fileprovider
: This is the authority of the Content Provider. It identifies the specific application and its file provider that is managing the data. In this case, it points to a file provider associated with an application developed by “cz.mobilesoft,” likely an “AppBlock” or similar application that blocks or manages other apps./cache/blank.html
: This is the path within the Content Provider. It specifies the particular resource being accessed./cache/
: This indicates that the resource is located within the application’s cache directory.blank.html
: This is the name of the file being referenced, a simple HTML file, likely used as a placeholder or a default page within the application’s functionality.
Why You Can’t Hack Around It in ObjC or Java Either
“Fine, I’ll go around the WebView. I’ll read the cache files directly using native APIs.”
Sorry that also fails.
On iOS, the WebView cache lives inside WKWebView’s internal sandbox, inside a hashed folder. There is no public API to list or read those cached AppCache files.
On Android, the WebView cache path is usually something like:
/data/data/com.yourapp/cache/webviewCache
But the filenames are hashed and not tied to URLs, and even if you scan them, you can’t reconstruct the original file content safely.
The Real Fix Don’t Read AppCache
Instead of trying to read AppCache, take control of caching yourself.
Cache Your File Manually Using LocalStorage or IndexedDB
if (navigator.onLine) {
fetch("/abcweb/js/abc.scripts.min.js")
.then(res => res.text())
.then(code => localStorage.setItem("cached_script", code));
} else {
const code = localStorage.getItem("cached_script");
eval(code); // Use carefully
}
With this approach, you never depend on AppCache to serve files back to you.
Use Service Workers AppCache’s Modern Successor
AppCache is deprecated for a reason. Service Workers are far more powerful, and most importantly, they let you read cached content manually.
Here’s a basic service worker fetch handler:
self.addEventListener("fetch", event => {
event.respondWith(
caches.match(event.request).then(cached => cached || fetch(event.request))
);
});
With this, you can later read the cache like:
caches.open('your-cache-name').then(cache => {
cache.match('/abcweb/js/abc.scripts.min.js').then(response => {
response.text().then(code => console.log(code));
});
});
This gives you true control something AppCache never allowed.
Native Layer Workarounds (ObjC & Java)
Let’s be honest: native access to AppCache content is not reliable. But if you must, there are partial hacks.
iOS Objective-C Attempt
You might snoop Library/Caches/WebKit
paths, but success depends on iOS version, WebKit internals, and timing. It’s not production-safe.
Android Java Hack
In Android:
File webviewCache = new File(getCacheDir(), "webviewCache");
for (File file : webviewCache.listFiles()) {
Log.d("FILE", file.getAbsolutePath());
}
You’ll see random hashed files. But they are not readable JS files. They’re compressed and stored in Chromium cache format.
Conclusion: Native access is a dead end unless you store the files yourself.
Final Thought
Instead of wrestling with AppCache’s limitations, it’s smarter to take control of your own caching strategy. AppCache was never meant to expose file contents only to serve them silently in the background. So rather than trying to read cached files directly, store them yourself using LocalStorage, IndexedDB, or Service Workers. It’s cleaner, more reliable, and gives you full control over how your app behaves offline.