问题
I'm using AngularJS and I'm developing SPA. My goal was to provide offline brwosing. JSON data can be easily stored in js variables, images can be cached in Image objects.
So now I'm wondering.. if one person goes offline and tries to browse the content, what will happen?
1) the browser can't load the image because, being offline, it can't check what is the most-recent version of the image (the one cached or the one online)
2) the browser finds a reference for the image in the cache. The cached image is loaded even if the browser can't check the online image for the most-recent version
NOTE: THIS IS NOT A DUPLICATE QUESTION.
The fact I'm using Angular doesn't matter for the problem. There will be other people using other frameworks and looking for a general solution.
Secondly.. those answers just points out to use HTML5 and service workers. Things not related to AngularJS.
回答1:
The unsatisfactory, but honest answer is "it depends". Unless you use specific instructions by listing your image in an AppCache or ServiceWorker, the browser cache may or may not show your images. Older browsers showed the HTML document and the content it had when you opened the file offline, but browsers that do have features like the ones mentioned are more aggressive in telling you that you are offline and will not show the page at all. The reason is that browser makers could not guarantee a good experience so instead of showing a document that may or may not display the images you get a "you are offline" message.
You can instruct browsers to cache images for a long time, which increases the likelihood of them being displayed https://developers.google.com/speed/docs/insights/LeverageBrowserCaching but there is no clean way to instruct the browser not to look for a newer version of them unless you specify it in AppCache or a ServiceWorker.
回答2:
Browser caching is not a suitable replacement for making a site retain functionality when the client isn't connected to the internet (offline).
Take a look at: Makes Angular JS works offline
There are a number of ways in which you can make assets available to offline users.
回答3:
As a companion to Alex Johnson's answer, you should probably check out the Service Workers API. There is also a good explanation of the technology in this Github repo. It will allow you to ensure your architecture supports a pleasurable offline experience.
回答4:
I recommend base64 encoding your images, which essentially turns them into strings. Base64 strings can be used as image source. You can save these strings into localStorage, and read them when you're offline.
Check out this code:
<img src="#" class="myImage" />
<style type="text/css">
.myImage {
content: url('data:image/gif;base64,R0lGODlhEAAQALMPAAAAAIAAAACAAICAAAAAgIAAgACAgMDAwICAgP8AAAD/AP//AAAA//8A/wD//////yH5BAEAAA8ALAAAAAAQABAAQAQ78EkJqp10LaB759sDVh4ZiqVVTqC3om6smVvcAmz74Zioz7zMRmfC/WTAGXI0Ws5gtc+HhXz2fJagJAIAOw==');
}
</style>
回答5:
Ok, after reading your answers, the most useful was the piece in @Alexjohnson answer. Makes Angular JS works offline says something about browser caching:
The native "old" caching won't work here, because it still requires to communicate with the server to have the "304 Not Modified" http code.
But I've tried this technique, and it strangely works. Guys please try this by yourself, you'll see, by going offline after image preloading, the image will be displayed. And if you put another img
element with a reference to the web image, this won't be loaded.
If you refresh the page the image cached will be displayed.
What do you think about this?
Here is an example:
<html>
<head>
</head>
<body>
<script type="text/javascript">
var my_image1 = new Image();
var my_image2 = new Image();
var images = 2, count_images = 0;
// notify the user that the image has been preloaded, and reveal the
// button to use the preloaded image
function notify()
{
count_images++;
if (count_images == images) {
document.getElementById('preloadbutton2').style.display = 'none';
document.getElementById('after_preload').style.display = 'block';
}
console.log('finito');
}
function preload()
{
my_image1.onload = notify;
my_image2.onload = notify;
my_image1.src = 'https://mir-s3-cdn-cf.behance.net/project_modules/max_1200/47351a35419617.56f6327af207a.gif';
my_image2.src = 'https://mir-s3-cdn-cf.behance.net/project_modules/max_1200/2150fb35419617.56f6327b44e47.gif';
}
// using only the file name, we can take advantage of the preloaded image
function use_preloaded_image()
{
document.getElementById('offline_1').src = my_image1.src;
document.getElementById('offline_2').src = my_image2.src;
}
</script>
<!-- INSTRUCTIONS
OPEN THIS FILE IN THE BROWSER WITH ONLINE NETWORK, CLICK ON THE BOTTON TO PUT IMAGES IN CACHE
GO OFFLINE AND REALOAD THE PAGE (INSPECT ID DOF THE IMAGES: IMAGES FRO MTHE WEB WON'T BE LOADED, THE ONES CACHED WILL BE SHOWED)
RELOAD THE PAGE: AS BEFORE, IMAGES FROM CACHE ARE STILL THERE, THEY'RE VISIBLE
-->
<!-- IMAGES FROM THE WEB -->
<img src="https://mir-s3-cdn-cf.behance.net/project_modules/max_1200/5aa12735419617.56f6327ab4f72.gif" width="500px" />
<img src="https://mir-s3-cdn-cf.behance.net/project_modules/max_1200/74f16635419617.56f6327adcf75.gif" width="500px" />
<br/>
<!-- IMGES PUT IN CACHE ON BUTTON CLICK -->
<input type="button"
id="preloadbutton2"
value="Preload Image"
onclick="preload();this.value='Loading. Please wait...'" />
<div id="after_preload" style="display: none">
<input type="button" value="Use Preloaded Image"
onclick="use_preloaded_image()" /><br />
<img src="" id="offline_1" width="500px" />
<img src="" id="offline_2" width="500px" />
</div>
</body>
</html>
来源:https://stackoverflow.com/questions/37660997/are-cached-images-loaded-by-the-browser-when-offline