When I make a request to a Google Api font (e.g. https://fonts.googleapis.com/css?family=Roboto:400), the last-modified header is always changing to the current time.
Caching doesn't work as a result and the file has to be downloaded every load. Is there a reason for this? Should I download the file and host it on my server?
Should I download the file and host it on my server?
Absolutely not, because the content of the CSS files is dynamic and has different content for every user agent. This is because not all browsers support all font formats. Some require WOFF/WOFF2, others require EOT, TTF or SVG. By downloading and serving the file statically you will break font support for all other browsers.
Interestingly though, I do not see a last-modified header at all:
HTTP/1.1 200 OK
Access-Control-Allow-Origin: *
Content-Type: text/css
Alt-Svc: clear
Alternate-Protocol: 443:quic,p=0
X-XSS-Protection: 1; mode=block
Server: GSE
Expires: Mon, 14 Dec 2015 09:14:21 GMT
Timing-Allow-Origin: *
Cache-Control: private, max-age=86400
Date: Mon, 14 Dec 2015 09:14:21 GMT
Content-Length: 222
Connection: close
X-Content-Type-Options: nosniff
X-Frame-Options: SAMEORIGIN
The Expires header indeed is the same as the Date - so it expires at the time the ressource was loaded. The max-age option of Cache-Control though has higher precedence. So the file should be cached by the browser for 1 day.
Related
I'm using Cloudfront (with Cloudflare in front) to serve the following file:
https://app.astrobin.com/assets/i18n/en.po?version=1623337803841
These are the response header at the time of writing:
accept-ranges: bytes
age: 2825
cf-cache-status: DYNAMIC
cf-ray: 65d3e1df6fe70f9a-VIE
cf-request-id: 0a984b7fa400000f9ac0139000000001
content-length: 6626
content-type: application/octet-stream
date: Thu, 10 Jun 2021 16:12:37 GMT
etag: "6336cef3a9da96c3c432813762cd7d70"
expect-ct: max-age=604800, report-uri="https://report-uri.cloudflare.com/cdn-cgi/beacon/expect-ct"
last-modified: Thu, 10 Jun 2021 15:17:27 GMT
nel: {"report_to":"cf-nel","max_age":604800}
report-to: {"endpoints":[{"url":"https:\/\/a.nel.cloudflare.com\/report\/v2?s=TipuJtVNh6YvmqS4rzXv5mtQ%2BUKVHBvok88InKPm%2FNGqK13b2EX1%2BxMEuMfCgp4qslhW0xc1qeIzX1xpUzNW5u5rC8Di3lsb4zNqaoN0zhhH5E3wbizW%2FjlbqD5C"}],"group":"cf-nel","max_age":604800}
server: cloudflare
via: 1.1 3d4555926457517be3e728d2175d92a3.cloudfront.net (CloudFront)
x-amz-cf-id: MfDo647EBTxmyo7TZ-sseALca4bmzBPdPPnuiesvGjNnlkgqLzgwDA==
x-amz-cf-pop: VIE50-C2
x-cache: Hit from cloudfront
The following image is my Cloudfront "behavior" rule for that file:
I don't have any Page Rules in Cloudflare for this file.
I'm performing multiple requests to this file, for testing purposes, but the file is never fetched from Chrome's disk or memory cache. It always goes to the network.
As you can see from the request URL, I append the timestamp of the last known modification to this file, for cache-busting purposes, so I would like the file to be cached in the browser.
What am I missing?
Thanks!
Browser caching is determined by the caching headers (namely Cache-Control or Expires) in the response from the origin server. But the response you listed doesn't have such a header, so it's up to the browser to determine how long the resource is considered fresh.
If you want the browser to use a particular cache policy you should add a Cache-Control header to the response.
I have to, sadly, poll an endpoint and update another system when the data changes. I wrote a loop (with a sleep statement so I don’t DOS the server):
require 'nokogiri'
require 'open-uri'
desired_data = 'foo'
data = nil
url = nil
while data != desired_data do
sleep(2)
url = "https://elections.wi.gov/index.php/elections-voting/statistics"
doc = Nokogiri::HTML.parse(open(url))
puts doc
# do some nokogiri stuff to extract the information I want.
# store information to `data` variable.
end
# if control is here it means the data changed
This works fine except when the server updates, open(url) still returns the old content (even if I restart the script).
It seems like there may be some caching at play. How do I disable it?
Here are the HTTP headers returned:
HTTP/2 200
date: Fri, 02 Oct 2020 14:00:44 GMT
content-type: text/html; charset=UTF-8
set-cookie: __cfduid=dd8fca84d468814dd199dfc08d45c98831601647244; expires=Sun, 01-Nov-20 14:00:44 GMT; path=/; domain=.elections.wi.gov; HttpOnly; SameSite=Lax; Secure
x-powered-by: PHP/7.2.24
cache-control: max-age=3600, public
x-drupal-dynamic-cache: MISS
link: <https://elections.wi.gov/index.php/elections-voting/statistics>; rel="canonical"
x-ua-compatible: IE=edge
content-language: en
x-content-type-options: nosniff
x-frame-options: SAMEORIGIN
expires: Sun, 19 Nov 1978 05:00:00 GMT
last-modified: Fri, 02 Oct 2020 12:47:38 GMT
vary: Cookie
x-generator: Drupal 8 (https://www.drupal.org)
x-drupal-cache: HIT
x-speed-cache: HIT
x-speed-cache-key: /index.php/elections-voting/statistics
x-nocache: Cache
x-this-proto: https
x-server-name: elections.wi.gov
access-control-allow-origin: *
x-xss-protection: 1; mode=block
cache-control: no-store, no-cache, must-revalidate, post-check=0, pre-check=0
cf-cache-status: DYNAMIC
cf-request-id: 058b368b9f00002ff234177200000001
expect-ct: max-age=604800, report-uri="https://report-uri.cloudflare.com/cdn-cgi/beacon/expect-ct"
server: cloudflare
cf-ray: 5dbef38c3b6a2ff2-ORD```
If it matters, I’m using Ruby 2.7 on macOS Big Sur.
It might be a problem on the Drupal 8 website itself as it has its own cache manager - and it seems like there's a cache per user somewhere if you have new content using a web browser.
It is easy to see which cache contexts a certain page varies by and which cache tags it is invalidated by: one must only look at the X-Drupal-Cache-Contexts and X-Drupal-Cache-Tags headers!
But those headers are not available in your list. If you're in touch with the website's developers ask them to do the following:
You can debug cacheable responses (responses that implement this interface, which may be cached by Page Cache or Dynamic Page Cache) by setting the http.response.debug_cacheability_headers container parameter to true, in your services.yml. Followed by a container rebuild, which is necessary when changing a container parameter.
That will cause Drupal to send X-Drupal-Cache-Tags, X-Drupal-Cache-Contexts headers.
I'm a bit unsure what it happening here but ill try to explain what is happening and maybe write a better question once i figured out what i'm actually asking.
I have just installed Varnish which seems awesome for my request times. It is a Magneto 2 store which I have followed the default configuration within dev docs for varnish.
My Issue
Currently my issue is that the browser seems to be caching the page until i click refresh. I believe i am successfully flushing / purging the cache with magento / varnish. As when using Curl to request the page i can see a new page is generated each time i flush cache and just serves cached page if i don't.
Within chrome and firefox however on my client pc however the whole page markup seems to be cached (when clicking a link to page or pasting url in browser) until clicking refresh which seems to reload the real page. When deploying new static files etc as the old resources are still in the cached markup and the new location for resources is signed e.g. version1234/styles.css and not matching the markup i get CSS less pages until client clicks refresh and loads the actual markup from server?
How can i setup caching so that this does not happen?
Curl -IL result of URL:
HTTP/1.1 200 OK
Date: Fri, 24 Nov 2017 12:08:32 GMT
Strict-Transport-Security: max-age=63072000; includeSubdomains
X-Frame-Options: DENY
X-Content-Type-Options: nosniff
Expires: Sun, 26 Nov 2017 15:55:17 GMT
Cache-Control: max-age=186400, public, s-maxage=186400
Pragma: cache
X-Content-Type-Options: nosniff
X-XSS-Protection: 1; mode=block
X-Frame-Options: SAMEORIGIN
Vary: Accept-Encoding
X-UA-Compatible: IE=edge
Content-Type: text/html; charset=UTF-8
X-Magento-Cache-Control: max-age=186400, public, s-maxage=186400
X-Magento-Cache-Debug: HIT
Grace: none
age: 0
Accept-Ranges: bytes
Connection: keep-alive
Browser caching takes please because of these headers being sent:
Expires: Sun, 26 Nov 2017 15:55:17 GMT
Cache-Control: max-age=186400, public, s-maxage=186400
You should adjust your server configuration so that those are not sent for PHP. Most likely you have a configuration block in nginx or .htaccess that applies to the whole website, as opposed to just static files.
Here's the curl -I response to my Javascript file:
HTTP/1.1 200 OK
Content-Type: text/javascript
Content-Length: 72640
Connection: keep-alive
Date: Sat, 18 Feb 2017 16:12:06 GMT
Cache-Control: 86400
Last-Modified: Wed, 15 Feb 2017 15:09:28 GMT
ETag: "a6ee06ff5e49a4290bb2aabe5e0f9029"
Server: AmazonS3
Vary: Accept-Encoding
Age: 1173
X-Cache: Hit from cloudfront
Via: 1.1 3b17302562f1709d8b6c9f7be1.cloudfront.net (CloudFront)
I can see the Cache-Control tag there. Not sure what the Vary and the ETag are doing, but so be it. Does this somehow specify to a user's browser NOT to cache this file? Why are Pingdom or Goog PageSpeed not recognising this as a browser-cacheable file?
Your Cache-Control header is present, but the value is not actually valid. The correct format looks like this:
Cache-Control: max-age=86400
The number, by itself, is meaningless.
ETag: is the entity tag -- an opaque value that uniquely identifies the current content of a given URL. If the content changes, the ETag will also change. A browser with a cached copy may use this value for subsequent requests to ask that the server only return the content if it differs, by sending an If-None-Match: request header, including the last-seen ETag.
Vary: tells the browser that certain changes to the request may generate a different response. Unlike browsers, curl doesn't advertise its ability to support gzipped payload unless you specify the --compressed option. Adding that option when invoking curl triggers the addition of Accept-Encoding: gzip to the request, which may trigger the response to be compressed if you have that option enabled in CloudFront.
I am working on a web application which has user management in place. I find a concerning issue in firefox related to Work Offline. Following are the steps describing the scenario:
User logs in to the application
User performs some action and logs out of the application
If the user now enables Work Offline mode in firefox, he/she can use browser back to access the last page. However, this page is supposed to be secure.
In my opinion this is a data security issue as any other user can apply this technique to fetch valuable information of the last user.
I have used cache control headers to communicate to the browser that HTML content should not be cached. Following are the response headers used:
HTTP/1.1 200 OK
Date: Tue, 05 May 2015 10:39:30 GMT
Server: Apache/2.4.9 (Unix) OpenSSL/0.9.8za
Cache-Control: no-cache, no-store
Expires: Wed, 31 Dec 1969 23:59:59 GMT
Content-Type: text/html;charset=UTF-8
Content-Language: en
Vary: Accept-Encoding
Content-Encoding: gzip
X-Frame-Options: SAMEORIGIN
Keep-Alive: timeout=5, max=100
Connection: Keep-Alive
Transfer-Encoding: chunked
I have used
Cache-Control: no-cache, no-store
Expires: Wed, 31 Dec 1969 23:59:59 GMT
I have noted this vulnerability in applications like Facebook. Is this resolvable? Thank you.