How to prevent Chrome from using disk cache when the assets change? - google-chrome

Setup
I have a static site served by Nginx. I use Webpack to build the assets with a contenthash in the filename:
index.html
main.723f2b08bd448896ca78.js
main.18a850dffbe46cca9feb.css
When I edit my JavaScript code and redeploy the site, the root directory changes to:
index.html
main.08ddcf9a702a6772ce2d.js # <- new hash
main.18a850dffbe46cca9feb.css
Problem
When I open a new tab in Chrome, type my domain name, and press Enter - in the Network tab, I see that Chrome is still loading the old files:
Name Status Type Initiator Size Time
mydomain.com 200 document Other (disk cache) 4 ms
main.723f2b08bd448896ca78.js 200 script (index) (disk cache) 17 ms
main.18a850dffbe46cca9feb.css 200 stylesheet (index) (disk cache) 13 ms
When I click example.com, the HTML in Response includes the old script:
<script src="/main.723f2b08bd448896ca78.js"></script
Also, the Response Headers on index.html are outdated:
Content-Encoding: gzip
Content-Type: text/html
Date: Thu, 26 Jan 2023 09:21:31 GMT
ETag: W/"63d06108-202"
Last-Modified: Tue, 24 Jan 2023 22:51:52 GMT
X-DNS-Prefetch-Control: off
Furthermore, when I click on main.723f2b08bd448896ca78.js, the Response Headers are also out-of-date:
Accept-Ranges: bytes
Content-Length: 605458
Content-Type: application/javascript
Date: Thu, 26 Jan 2023 09:21:31 GMT
ETag: "63d06108-93d12"
Last-Modified: Tue, 24 Jan 2023 22:51:52 GMT
If I reload the page, Chrome loads the new files correctly. But if I then open a new tab again, type the domain, and press Enter - it still loads the old assets! This leaves me with a hard page reload (Ctrl + Shift + R) which finally resets the cache.
Expectation
When I load my site in Incognito I get the correct files as expected:
Name Status Type Initiator Size Time
mydomain.com 200 document Other 557 B 634 ms
main.08ddcf9a702a6772ce2d.js 200 script (index) 606 kB 1.28 s
main.18a850dffbe46cca9feb.css 200 stylesheet (index) 87.2 kB 497 ms
index.html Response:
<script src="/main.08ddcf9a702a6772ce2d.js"></script
index.html Response Headers:
Connection: keep-alive
Content-Encoding: gzip
Content-Type: text/html
Date: Thu, 26 Jan 2023 10:33:44 GMT
ETag: W/"63d249c7-202"
Last-Modified: Thu, 26 Jan 2023 09:37:11 GMT
Transfer-Encoding: chunked
main.08ddcf9a702a6772ce2d.js Response Headers:
Accept-Ranges: bytes
Connection: keep-alive
Content-Length: 605595
Content-Type: application/javascript
Date: Thu, 26 Jan 2023 10:33:44 GMT
ETag: "63d249c7-93d9b"
Last-Modified: Thu, 26 Jan 2023 09:37:11 GMT
Question
I don't understand what I'm doing wrong - Nginx is returning new values for Etag and Last-Modified. The contenthash changes between deployments. Yet the JS file is still cached very aggressively. This problem happens to me and other people using the site. In this case, it caused a white screen of death, and I had to tell everyone to do a hard page reload (which is foreign and bewildering to the end users).
Is there a solution for this? I don't mind disk cache but how do I tell Chrome not to use it when the asset file changes? Is this an Nginx misconfiguration?
Thank you.

It's your job to tell the browser how long it can cache a resource. You do so by setting the Cache-Control response header (MDN). If you don't set it, the browser is free to decide for itself how long is appropriate. That seems to be what's happening in your case.
Simply set Cache-Control: no-cache on your index.html response header and this problem will go away. The page will still be cached by the browser, but the browser won't use it without first checking with the server to see if it's still current (that's what the ETag is for).
For your static resources, though, you should set a long cache time, since the whole purpose of versioning file names like that is to allow any given one to be immutable.

Related

Cookie value is not getting set

I have made a module in nginx to secure cookie.I encrypted the cookie with AES and modified the original cookie with the encrypted value.
If i modify the original cookie with some other value, then its working fine, say i changed cookie value from abc to xyz it works but when i change abc to encrypted abc chrome is not able to save it.
I can see it in the response headers in chrome, but the cookie is not stored by chrome and not sent by chrome for further requests.
Connection:keep-alive
Content-Length:612
Content-Type:text/html
Date:Sun, 15 Feb 2015 14:00:59 GMT
ETag:"54c1c5ae-264"
Last-Modified:Fri, 23 Jan 2015 03:53:18 GMT
Set-Cookie:my_login=2%B9%B2C%BB%E3%B5 }%EA%E8o%DC%B4%BF%F1%BB%BD|%EA%BF%F2K%A4?m7S%88%A7
Also live http headers extension in chrome shows the value of set-cookie as undefined.
HTTP/1.1 200 OK
Accept-Ranges: bytes
Connection: keep-alive
Content-Length: 612
Content-Type: text/html
Date: Sun, 15 Feb 2015 14:00:59 GMT
ETag: "54c1c5ae-264"
Last-Modified: Fri, 23 Jan 2015 03:53:18 GMT
Set-Cookie: undefined
Any insight will be help.Thanks
1st, you might need to remove whitespaces
2nd, apparently you're sending cookie in a binary format, which can't be set.
here is a quick solution, encrypt this cookie (further) to base64 before sending it to the browser. That should solve your problem.

Chrome + CORS + cache - requesting same file from two different origins

I'm experiencing an issue with Chrome that I can't seem to fully understand, I'm curious if folks here have dealt with it before. This doesn't reproduce in Firefox. The steps are as follows:
Start incognito Chrome, navigate to https://foo.mysite.com and have the JS on the page make a GET ajax request to S3 for https://s3.amazonaws.com/mystuff/file.json . You get back a 200 response with:
HTTP/1.1 200 OK
x-amz-id-2: somestuffhere
x-amz-request-id: somestuffhere
Date: Tue, 14 Oct 2014 03:06:41 GMT
Access-Control-Allow-Origin: https://foo.mysite.com
Access-Control-Allow-Methods: GET
Access-Control-Max-Age: 3000
Access-Control-Allow-Credentials: true
Vary: Origin, Access-Control-Request-Headers, Access-Control-Request-Method
Cache-Control: max-age=86400
Content-Encoding: gzip
Last-Modified: Sun, 05 Oct 2014 00:29:53 GMT
ETag: "fe76607baa40a793eb3b3cbd373a3fb8"
Accept-Ranges: bytes
Content-Type: application/json
Content-Length: 5609
Server: AmazonS3
Open a second tab, navigate to https://bar.mysite.com and have its JS make a GET ajax request to S3 for the same file https://s3.amazonaws.com/mystuff/file.json . Get back the following 304 response:
HTTP/1.1 304 Not Modified
x-amz-id-2: somestuffhere
x-amz-request-id: somestuffhere
Date: Tue, 14 Oct 2014 03:06:58 GMT
Access-Control-Allow-Origin: https://bar.mysite.com
Access-Control-Allow-Methods: GET
Access-Control-Max-Age: 3000
Access-Control-Allow-Credentials: true
Vary: Origin, Access-Control-Request-Headers, Access-Control-Request-Method
Cache-Control: max-age=86400
Last-Modified: Sun, 05 Oct 2014 00:29:53 GMT
ETag: "fe76607baa40a793eb3b3cbd373a3fb8"
Server: AmazonS3
Open a third tab, navigate to https://foo.mysite.com (the first site) and repeat the same steps as in 1. Chrome kills the response for CORS reasons and reports the following:
XMLHttpRequest cannot load https://s3.amazonaws.com/mystuff/file.json. The 'Access-Control-Allow-Origin' header has a value 'https://bar.mysite.com' that is not equal to the supplied origin. Origin 'https://foo.mysite.com' is therefore not allowed access.
What's the story here? This doesn't reproduce in Firefox. In Firefox I'm happily getting a 304 in both steps 2 and 3, which I would expect to see in Chrome as well.
A temporary workaround for this issue in Chrome is to set Cache-Control: no-cache on the file in S3, but then I'm forcing our clients to be re-downloading that file for no good reason, so it's not a real solution.
Is this intended and documented behavior? Is this a bug with Chrome? Any other thoughts?
Looks like this is caused by Chromium issue 260239
I found this blog that help: Add Vary headers to S3
It helped by adding Vary headers to all XHR request.
I did run into a problem with html request (i.e. ) but I was able to overcome that by using hackround#2 described here:https://serverfault.com/a/856948
TL;DR of hack#2 is to use a "dummy" query string parameter that differs for HTML and XHR or is absent from one or the other. Example:
<img src="https://s3.png?x-request=html">
I just add a timestamp in request URL to force load the asset from S3 again, not from cache, such as xxxx?timestamp=yyyy

how to identify errors in manifest file

I am making the manifest file work for my web page but it is not working when turn of internate and open web page on ipad it says connect to internet.how to solve this issue i have given all the resources used in web page in the manifest file but still it is not working
Below is My Manifest File
CACHE MANIFEST
CACHE:
index.html
brd_icon.png
newstyle_tester.css
draxxin.pdf
exede.pdf
js/jquery-1.7.2.min.js
js/script.js
js/jquery.queryloader2.js
image/startbutton.png
image/mockup_splash_1.png
image/testing_file_3.png
image/overview.gif
image/strategy.gif
image/draxxin.gif
image/excede.gif
image/reference.gif
image/results.gif
image/seperator.png
image/overview_active.png
image/strategy_active.png
image/draxxin_active.png
image/excede_active.png
image/result_active.png
image/references_active.png
image/pageone_image.png
image/whiteslide.png
image/option.png
image/option_1.png
image/pagetwo_graph_one.png
image/pagetwo_graph_two_4.png
image/optiononeone.png
image/optiononetwo.png
image/optiontwofirst.png
image/optiontwosecond.png
image/backward.png
image/forward.png
image/button_7days.png
image/button_14days.png
image/close.png
image/popup_page_1.png
image/popup_1_page_2.png
image/popup_2_page_2.png
image/popup_page_3.png
image/popup_page_4.png
image/popup_1_page_5.png
image/popup_2_page_5.png
image/popup_3_page_5.png
image/popup_4_page_5.png
image/smallicon_1.png
image/smallicon_2.png
image/bg_img_lightbox.png
image/tag.png
image/result_graphic_1.png
image/result_graphic_2.png
image/result_graphic_3.png
image/graph1.png
image/graph2.png
image/graph3a.png
image/graph4.png
image/graph5.png
image/graph_one.png
image/graph_three.png
image/bottle_1.png
image/bottle_2.png
image/arrow_1.png
Your problem is that you've not configured the content type header correctly on your server. Here's the response to the HTTP request for cache.manifest:
HTTP/1.1 200 OK
Date: Tue, 08 May 2012 09:33:41 GMT
Server: Apache
Last-Modified: Tue, 08 May 2012 05:07:32 GMT
Etag: "733106-652-4bf7f5d3692a8"
Accept-Ranges: bytes
Content-Length: 1618
Keep-Alive: timeout=15, max=100
Connection: Keep-Alive
Content-Type: text/plain
See that last line? It should be text/cache-manifest. Change the content type in your server configuration. For Apache you can add this line to the server config or in an .htaccess file:
AddType text/cache-manifest appcache manifest

why do I see the source code (html) of some web pages?

Most web pages are normally parsed and of course I don't see tags like <html> or <a href=>.
But, when I open some web sites, the source code pops up.
Try this
http://mediacomp-jes.googlecode.com/svn-history/r68/jes/JESHelp/auxHelp/mediaToolsOverview.html
So I saved this web page and reopened locally using firefox, everything seems normal again.
any reasons?
You're viewing the file in an SVN repository browser. They must have the encoding for the documents in these directories set to render as plain text. I am using chrome and saw the same thing. It's by design in this case.
As everybody says, it is the server side (Apache) configuration. You can confirm this by issuing HEAD request.
curl -I http://mediacomp-jes.googlecode.com/svn-history/r68/jes/JESHelp/auxHelp/mediaToolsOverview.html
returns
HTTP/1.1 200 OK
Date: Thu, 29 Dec 2011 00:27:49 GMT
Server: Apache
Last-Modified: Thu, 16 Oct 2008 18:13:57 GMT
ETag: "2//jes/JESHelp/auxHelp/mediaToolsOverview.html"
Accept-Ranges: bytes
Expires: Thu, 29 Dec 2011 00:30:49 GMT
Content-Length: 1802
Content-Type: text/plain
Cache-Control: public, max-age=180
Age: 0
Notice that Content-Type says "text/plain"
You're looking at a svn repository, and the response type is text/plain instead of text/html, so the browser renders it as text instead of html
SVN or not the important for the browser is the header Content-Type - the most of the pages are rendered as html, no matter the extension or absence of such, because of the header. Another effect obviously will be that JavaScript won't be executed.
About the Content-Type ietf and MIME types list Wikipedia
Header Content-Type: text/html; charset=utf-8 - rendered
lynx -head -dump http://stackoverflow.com/questions/8662745/why-do-i-see-the-source-code-html-of-some-web-pages
HTTP/1.1 200 OK
Cache-Control: public, max-age=60
Content-Length: 41163
Content-Type: text/html; charset=utf-8
Expires: Thu, 29 Dec 2011 00:26:08 GMT
Last-Modified: Thu, 29 Dec 2011 00:25:08 GMT
Vary: *
Date: Thu, 29 Dec 2011 00:25:08 GMT
Connection: close
Header Content-Type: text/plain - displayed as text
lynx -head -dump http://mediacomp-jes.googlecode.com/svn-history/r68/jes/JESHelp/auxHelp/mediaToolsOverview.html
HTTP/1.0 200 OK
Date: Thu, 29 Dec 2011 00:26:00 GMT
Server: Apache
Last-Modified: Thu, 16 Oct 2008 18:13:57 GMT
ETag: "2//jes/JESHelp/auxHelp/mediaToolsOverview.html"
Accept-Ranges: bytes
Expires: Thu, 29 Dec 2011 00:29:00 GMT
Content-Length: 1802
Content-Type: text/plain
Cache-Control: public, max-age=180
Age: 0
This is because this page has been encoded and then put in the page. So if you look at the page source your see it is written like <html> <head> <title> obviously because some one wants to show the page mark up. Nothing wrong with your browser etc

Mercurial Web Server - Why am I downloading a .bz2.tar file instead of a .tar.bz2 file?

It is my understanding that a .tar file contains directories and other files, and a .bz2 is a file that's compressed with bzip2 compression.
Therefore, most tarballs with bzip2 compression end in:
.tar.bz2
Which is bzip2 compression applied to a tarball.
However, whenever I download source code from a Mercurial webserver, either the internal one that you get from:
hg serve
Or from BitBucket, I get something that ends in
.bz2.tar
Which doesn't make sense to me, because you can't apply bzip2 compression on multiple files, which is why you need to "tar" them up first.
Is this a bug in Mercurial? Or is this a bug in my web browser (I've tried Google Chrome in Windows and Firefox in Ubuntu)? Or is this something that's just weird but doesn't make a difference?
The latest source that I downloaded was from http://bitbucket.org/bos/hgbook which is the repository for the Mercurial book.
I think I see the problem. The Content-Type header in the download is wonky:
% GET -Ssed http://host/mayorguard/archive/tip.tar.bz2
GET http://ry4an.org/hg/mayorguard/archive/tip.tar.bz2 --> 200 Script output follows
Connection: close
Date: Mon, 20 Sep 2010 19:01:00 GMT
Server: Apache/2.2.14 (Ubuntu)
Content-Type: application/x-tar
Client-Date: Mon, 20 Sep 2010 19:01:00 GMT
Client-Peer: 75.146.191.221:80
Client-Response-Num: 1
Client-Transfer-Encoding: chunked
Content-Disposition: attachment; filename=mayorguard-dee99508cd77.tar.bz2
Notice the Content-Disposition header suggests the browser use a filename with the correct extension, but the Content-Type header says it's a .tar file. When I do that download in Google Chrome I get a resulting file named mayorguard-hashid.tar.gz.tar which isn't right.
The example above was from hgweb and the one below is from bitbucket:
% GET -Ssed http://bitbucket.org/mailchimp/etsy-php/get/000000000000.bz2
GET http://bitbucket.org/mailchimp/etsy-php/get/000000000000.bz2 --> 200 OK
Cache-Control: max-age=1800
Connection: close
Date: Mon, 20 Sep 2010 19:05:16 GMT
Accept-Ranges: bytes
Server: nginx/0.7.67
Content-Length: 189
Content-Type: application/x-tar
Expires: Mon, 20 Sep 2010 19:35:16 GMT
Last-Modified: Mon, 20 Sep 2010 19:05:16 GMT
Client-Date: Mon, 20 Sep 2010 19:05:16 GMT
Client-Peer: 207.223.240.182:80
Client-Response-Num: 1
Content-Disposition: attachment; filename=etsy-php-000000000000.bz2
I'd say that Mercurial is giving bad info and the browser is overthinking the filename.
This is a bug in bitbucket, please report it to them: http://bitbucket.org/jespern/bitbucket/issues/new/