84860

How to make Safari send if-modified-since header?

When I generate a page I send headers

HTTP/1.1 200 OK Cache-Control: private Content-Type: text/html; charset=utf-8 Last-Modified: Mon, 04 Apr 2011 20:08:33 GMT Vary: Accept-Encoding Date: Mon, 11 Apr 2011 01:36:21 GMT Content-Length: 3019

then, when I try to get this page again all browsers send correct request and get 304 answer except Safari - it never sends if-modified-since. It always reloads whole page even it havnt been changed

Does this behavior of Safari known and what to do to make Safari work in right way?

Answer1:

Bart Lateur wrote a post about this, with a paragraph stating about Safari:

Safari takes this even one step further: if the header isn't a date in http standard form, then the header is simply dropped. It simply doesn't send an If- Modified-Since header on the next request.

Answer2:

I ran into this with Safari 8.0. Despite providing the Last-Modified header to Safari it would not provide the If-Modified-Since header on subsequent requests. The fix in my case was to additionally set the Expires header to the same html-date as the Last-Modified header.

Here's an example of what the successful exchange looks like:

<strong>Initial Request</strong>

Standard first request from Safari.

GET http://localhost/image Host: localhost Connection: keep-alive Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8 User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/38.0.2125.104 Safari/537.36 Accept-Encoding: gzip,deflate,sdch Accept-Language: en-US,en;q=0.8

<strong>Initial Response</strong>

I specify both the Expires and Last-Modified headers as the same valid html-date. I have not tried but I doubt Safari will honor an Expires header set to -1.

HTTP/1.1 200 OK Server: Apache-Coyote/1.1 Expires: Thu, 17 Jul 2014 19:50:58 GMT Last-Modified: Thu, 17 Jul 2014 19:50:58 GMT Content-Type: image/png Content-Length: 1143902 Date: Wed, 22 Oct 2014 15:33:40 GMT <<DATA>>

<strong>Subsequent Request</strong>

At last Safari provides the needed If-Modified-Since header.

GET http://localhost/image Host: localhost Connection: keep-alive Cache-Control: max-age=0 Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8 User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/38.0.2125.104 Safari/537.36 Accept-Encoding: gzip,deflate,sdch Accept-Language: en-US,en;q=0.8 If-Modified-Since: Thu, 17 Jul 2014 19:50:58 GMT

<strong>Subsequent Response</strong>

I can satisfyingly return a 304.

HTTP/1.1 304 Not Modified Server: Apache-Coyote/1.1 Expires: Thu, 17 Jul 2014 19:50:58 GMT Last-Modified: Thu, 17 Jul 2014 19:50:58 GMT Date: Wed, 22 Oct 2014 15:33:43 GMT

Answer3:

Safari is only partly free software. Other than holding your breath until Apple releases the whole of Safari as free software, as a Safari user you could use a caching proxy and configure it to break the spec and ignore the Cache-Control headers Safari sends.

Squid has the refresh_pattern directive, and I'm sure other proxies have similar functionality.

You can then configure Safari to use the proxy, or you can do it transparently in the spirit of upside-down-ternet.

Answer4:

In my testing, Safari is expecting either an "Expires" or "Cache-Control" header along with "Last-Modified".

Cache-Control: max-age=0, private Last-Modified: Thu, 17 Aug 2018 12:04:23 GMT

Or,

Expires: Thu, 17 Aug 2018 12:04:23 GMT Last-Modified: Thu, 17 Aug 2018 12:04:23 GMT

NOTE: "max-age" was required for Safari to honor the "Last-Modified"

Recommend

  • What is the difference between GetComponent ().enabled and .SetActive (false); in unity
  • Nginx raises 404 when using format => 'js'
  • How can I stop .htaccess redirecting a subdomain to the main site?
  • How to Cache Images Dynamically-Generated with PHP?
  • Concourse add file to docker image just once
  • Convert a 12 hour time format to 24 hour time format (keeping record of the day) in python
  • While loop won't end when I tell it in JavaScript
  • Packet modification with netfilter queue?
  • Generating random numbers directly inside a .htaccess file
  • PHP file_exists() anomaly
  • Scala using regex with or syntax in match case statement
  • Passing information to server-side function in a Google Docs Add On
  • Getting unread count in Sent Folder using Google Apps Script - GMail
  • How do I Dispose a HttpResponseMessage in my Web Api Method?
  • File extension of zlib zipped html page?
  • Salesforce Different WSDL files and when to use
  • Function calls are not supported. Consider replacing the function or lambda with a reference to an e
  • ASP.NET MVC Application won't update some controllers
  • Silverlight DependencyProperty.SetCurrentValue Equivalent
  • Zurb Foundation _global.scss meta styles for js?
  • Highlight and Bold text in JTextPane
  • Regex thinks I'm nesting, but I'm not
  • Bug in WPF DataGrid
  • How to recover from a Spring Social ExpiredAuthorizationException
  • TFS: Get latest causes slow project reloading
  • Javascript Callbacks with Object constructor
  • Join two tables and save into third-sql
  • JSON with duplicate key names losing information when parsed
  • How to limit post in wp_query
  • Hazelcast - OperationTimeoutException
  • How to make Safari send if-modified-since header?
  • Adding custom controls to a full screen movie
  • Web-crawler for facebook in python
  • How to pass list parameters for each object using Spring MVC?
  • How to set the response of a form post action to a iframe source?
  • Setting background image for body element in xhtml (for different monitors and resolutions)
  • Change div Background jquery
  • Qt: Run a script BEFORE make
  • JaxB to read class hierarchy
  • reshape alternating columns in less time and using less memory