Appcache - how to set right cache headers? - internet-explorer-11

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();
}

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

Related

How to serve a wbn (WebPackage/WebBundle) file from a web server?

does anyone know how to serve a web bundle so that it loads, rather than just downloading as a file?
Some disambiguation: There is a format called WebPackage (not to be confused with webpack), also called a Web Bundle. Files typically have the .wbn suffix. It contains html and js files and can be used to view websites offline. Useful for e.g. archiving websites or making websites that work well with intermittent network access. Download the file once, and you have all the assets you need for at last basic operation of the site.
The standard on how to serve a .wbn file is here:
https://wicg.github.io/webpackage/draft-yasskin-wpack-bundled-exchanges.html
However when I add the required headers in the web server, the .wbn file is just downloaded. If I drag the downloaded file onto my browser (google-chrome), the file is displayed as the website it contains, so unless there is some very subtle bug in there I believe that the format of the bundle is OK.
Here is a sample request:
Request URL: http://localhost/bundle/www-signed.wbn
Request Method: GET
Status Code: 200 OK
Remote Address: [::1]:80
Referrer Policy: strict-origin-when-cross-origin
and the server response:
Accept-Ranges: bytes
Connection: keep-alive
Content-Length: 4300
Content-Type: application/webbundle <-- Required by the standard
Date: Thu, 02 Sep 2021 12:00:24 GMT
ETag: "612ef7cb-10cc"
Last-Modified: Wed, 01 Sep 2021 03:47:23 GMT
Server: nginx/1.18.0 (Ubuntu)
X-Content-Type-Options: nosniff <-- required by the standard
If anyone has this working on a website or knows how to do it, I would love to have a look.
I had the same problem that the wbn file was just downloaded instead of executed.
I had to enable the web bundles feature even though my chrome version is 96+

HTML Header indicates image/jpeg, DevTools indicates document and cache is not working

I am trying to cache some images and using the DevTools of MS Edge to analyze the network.
The URL should return only the image via readfile($image) and I see the image correctly in the browser.
Response Headers:
HTTP/1.1 200 OK
Date: Mon, 25 May 2020 19:18:56 GMT
Server: Apache/2.4.38
Expires: Thu, 19 Nov 1981 08:52:00 GMT
Cache-Control: max-age=86400
Pragma: no-cache
Debugbar-Time: 1590434336
Debugbar-Link: https://blog.casa.spiti/?debugbar_time=1590434336
Keep-Alive: timeout=5, max=100
Connection: Keep-Alive
Transfer-Encoding: chunked
Content-Type: image/jpeg
The Network Tab of the Chrome Dev Tools shows document for the image.
Questions to this output:
What is this expire date of 1981? How do I change it?
Is this the reason why the image is not cached?
Why is the image being indicated as document? Is it because I use readfile()?
Impossible to answer without seeing your server config.
Shouldn’t be, cache-control is used in preference to Expires.
If you are loading the image directly in the browser it shows as document - even if it’s an image. That image is the document in that case. If you load the image as part of an HTML document, then it will show as Image in Dev Tools.

Can browser caching be controlled by HTTP headers alone w/o using hash names for asset files?

I'm reading it in Webpack docs:
The way it works has a pitfall: if we don’t change filenames of our resources when deploying a new version, browser might think it hasn’t been updated and client will get a cached version of it.
I'm curious, is it mandatory to use this mechanism with ugly file names main.55e783391098c2496a8f.js for assets in order to inform a browser that an asset file has changed?
Can it be controlled by HTTP headers only? There are multiple HTTP headers in the standard to control how browser caches assets, like:
Cache-Control: no-cache, no-store, must-revalidate
Pragma: no-cache
Expires: 0
Date: Wed, 24 Aug 2020 18:32:02 GMT
Last-Modified: Tue, 15 Nov 2024 12:45:26 GMT
ETag: x234dff
max-age: 12345
So can I use those headers alone? Or do I still have to bother about hash parts in file names main.55e783391098c2496a8f.js?
When user agent opens a page it must always get correct version of a source code. You have two options to achieve this:
Set Cache-Control, Expires and strong validator (ETag) response headers . This way you instruct user agent to perform relatively lightweight conditional request on each page load
Embed version in source code file URL and set Cache-Control and Expires response headers. This way you instruct user agent to cache source code with particural version forever
For more information check HTTP Caching article by Ilya Grigorik, HTTP conditional requests MDN page and this StackOverflow answer about resource revalidation.

Analysis of HTTP header

Hello I want to analyze & understand at first place and then optimize the HTTP header responses of my site. What I get when I fetch as Google from webmasters is:
HTTP/1.1 200 OK
Date: Fri, 26 Oct 2012 17:34:36 GMT // The date and time that the message was sent
Server: Apache // A name for the server
P3P: CP="NOI ADM DEV PSAi COM NAV OUR OTRo STP IND DEM" // P3P Does an e-commerse store needs this?
ETag: c4241ffd9627342f5f6f8a4af8cc22ed // Identifies a specific version of a resource
Content-Encoding: gzip // The type of encoding used on the data
X-Content-Encoded-By: Joomla! 1.5 // This is obviously generated by Joomla, there wont be any issue if I just remove it, right?
Expires: Mon, 1 Jan 2001 00:00:00 GMT // Gives the date/time after which the response is considered stale: Since the date is set is already expired, this creates any conflicts?
Cache-Control: post-check=0, pre-check=0 // This means site is not cached? or what?
Pragma: no-cache // any idea?
Set-Cookie: 5d962cb89e7c3329f024e48072fcb9fe=9qdp2q2fk3hdddqev02a9vpqt0; path=/ // Why do I need to set cookie for any page?
Last-Modified: Fri, 26 Oct 2012 17:34:37 GMT
X-Powered-By: PleskLin // Can this be removed?
Cache-Control: max-age=0, must-revalidate // There are 2 cache-controls, this needs to be fixed right? which one is preffected? max-age=0, must-revalidate? post-check=0, pre-check=0?
Keep-Alive: timeout=3, max=100 // Whats that?
Connection: Keep-Alive
Transfer-Encoding: chunked // This shouldnt be deflate or gzip ??
Content-Type: text/html
post-check
Defines an interval in seconds after which an entity must be checked for freshness. The check may happen after the user is shown the resource but ensures that on the next roundtrip the cached copy will be up-to-date.
http://www.rdlt.com/cache-control-post-check-pre-check.html
pre-check
Defines an interval in seconds after which an entity must be checked for freshness prior to showing the user the resource.
Pragma: no-cache header field is an HTTP/1.0 header intended for use in requests. It is a means for the browser to tell the server and any intermediate caches that it wants a fresh version of the resource, not for the server to tell the browser not to cache the resource. Some user agents do pay attention to this header in responses, but the HTTP/1.1 RFC specifically warns against relying on this behavior.
Set-Cookie: When the user browses the same website in the future, the data stored in the cookie can be retrieved by the website to notify the website of the user's previous activity.[1] Cookies were designed to be a reliable mechanism for websites to remember the state of the website or activity the user had taken in the past. This can include clicking particular buttons, logging in, or a record of which pages were visited by the user even months or years ago.
X-Powered-By: specifies the technology (e.g. ASP.NET, PHP, JBoss) supporting the web application.This comes under common non-standard response headers and can be removed.
Keep-Alive It is meant to reduce the number of connections for a website. Instead of creating a new connection for each image/css/javascript in a webpage many requests will be made re-using the same connection.
Transfer-Encoding: The form of encoding used to safely transfer the entity to the user. Currently defined methods are: chunked, compress, deflate, gzip, identity.

Fiddler doesn't decompress gzip responses

I use Fiddler to debug my application. Whenever the response is compressed by server, instead of decompressed response, Fiddler shows unreadable binary data:
/* Response to my request (POST) */
HTTP/1.1 200 OK
Server: xyz.com
Date: Tue, 07 Jun 2011 22:22:21 GMT
Content-Type: text/html; charset=utf-8
Transfer-Encoding: chunked
Connection: keep-alive
X-Powered-By: PHP/5.3.3
Expires: Thu, 19 Nov 1981 08:52:00 GMT
Cache-Control: no-store, no-cache, must-revalidate, post-check=0, pre-check=0
Pragma: no-cache
Content-Encoding: gzip
14
����������������
0
How can I get the response decompressed?
I use fiddler version 2.3.4.4 and just noticed that in the Inspectors tab ("Raw" sub-tab), above the response section (in case of gzip-ed response), appears "Response is encoded and may need to be decoded before inspection. Click here to transform."
If you click on that, the response becomes readable.
The settings are pretty much the default, I just installed Fiddler and did not change anything.
If you don't want to have to click per response as in the accepted answer, using the menu, click Rules -> Remove All Encodings.
From the fiddler faq
Q: I like to navigate around a site then do a "search" for a text on all the logged request/responses. I was curious if Fiddler automatically decompressed gzipped responses during search?
A: Fiddler does not decompress during searches by default, since it would need to keep both the compressed and decompressed body in memory (for data integrity reasons).
In current versions of Fiddler, you can tick the "Decode Compressed Content" checkbox on the Find dialog.
Here is a link to the site
http://www.fiddler2.com/fiddler/help/faq.asp