0
votes

I have created a simple manifest file which is hosted in iframe on the page.

The problem with this is that, the manifest is parsed correctly, but files are taken not from the cache.

With standard cache headers (manifest and each file definied in it has the private cache-control):

HTTP/1.1 200 OK
Cache-Control: private
Content-Type: text/cache-manifest; charset=utf-8
Content-Encoding: gzip
Vary: Accept-Encoding
Server: Microsoft-IIS/8.5
X-AspNetMvc-Version: 5.2
X-AspNet-Version: 4.0.30319
X-UA-Compatible: IE=Edge
Date: Fri, 06 Mar 2015 10:47:28 GMT
Content-Length: 1398

First time when I get to the page in IE11/Chrome/Firefox the appcache events are fired and all files are fetched. But when I click on the menu where is a link to current page, then in fiddler and in browser dev tools I see that, the files for this specific page are fetched from the server, not from the cache.

Then I change the manifest cache headers (for files headers are the same as before):

HTTP/1.1 200 OK
Cache-Control: private, max-age=0
Content-Type: text/cache-manifest; charset=utf-8
Content-Encoding: gzip
Expires: Fri, 06 Mar 2015 11:00:52 GMT
Vary: Accept-Encoding
Server: Microsoft-IIS/8.5
X-AspNetMvc-Version: 5.2
X-AspNet-Version: 4.0.30319
X-UA-Compatible: IE=Edge
Date: Fri, 06 Mar 2015 11:00:51 GMT
Content-Length: 1398

On all browser result is the same.

When the expires header for the manifest is set and I set it for the files defined in manifest, then on Firefox files are loaded from appcache, but after second request to each page. Shouldn't they be loaded from the cache when I got the the page for the first time? Cache was loaded on other page and page was refreshed by window.location.reload and swapCache was used. On each page the manifest is loaded by the same iframe (it it located on the main _Layout.cshtml).

In Chrome situation is similar to Firefox, but in this browser it is enought to get to each page for the first time to get the images from cache (I didn't mention I got only images, not js or css files in the manifest).

This is all good, but in IE11 it doesn't work. Situation is the same as at the beginning of my post. For first time all images from manifest are loaded, but later when I load any page, all images from this page are loaded again from the server, not from the cache. And this is persistent.

In IE10 I see these files are returned with the 302 status code, but I doesn't see it it taken from the appcache.

Using appcache there should not be any request to the server.

How can I get it to work in each browser?

The appcache it is a real madness to debug and to set it correctly.

I don't want to count how many hours I lost to set it the this current point and I see this is not the end of the journey.

[edit]

Maybe when I server the files to browser I should do it in other way? (return 304 or something...)

This is my http handler (I'm doing it in ASP.NET MVC, but it shouldn't be a problem):

public void ProcessRequest(HttpContext context)
    {
        var current = context.Request.CurrentExecutionFilePath;

        string extension = Path.GetExtension(current).ToLower();
        if (extension == ".json")
        {
            context.Response.ContentType = "application/json";
        }
        else if (extension == ".png")
        {
            context.Response.ContentType = "image/png";
        }
        else
        {
            throw new InvalidOperationException("Unsupported file type");
        }

        context.Response.Cache.SetExpires(DateTime.UtcNow.AddMinutes(30));

        var cache = context.Response.Cache;
        cache.SetMaxAge(new TimeSpan(0, 30, 0));


        var serverPath = context.Server.MapPath(current);
        byte[] image = File.ReadAllBytes(serverPath);

        context.Response.BinaryWrite(image);
        //context.Response.End();
    }
1

1 Answers

0
votes

I have implemented in my custom handler handling for the If-Modified-Since header and looks like it works properly. Additionally I added a line of code to refresh the source for iframe by

iframe.src = iframe.src