I have this code
header('Access-Control-Allow-Origin: *');
header('Access-Control-Allow-Methods: POST, GET, PUT, DELETE');
use app\components\FilesHandler;
$mimeType = FilesHandler::getType();
header("Content-Type: $mimeType");
echo FilesHandler::getFile();
And on the localhost machine an image has CORS headers, although it hasn't on a remote server.
How can I fix this?
Response headers from the remote server
Accept-Ranges: bytes
Cache-Control: max-age=315360000
Content-Length: 1521987
Content-Type: image/png
Date: Fri, 31 Jul 2020 05:07:17 GMT
ETag: "5f239615-173943"
Expires: Thu, 31 Dec 2037 23:55:55 GMT
Last-Modified: Fri, 31 Jul 2020 03:55:01 GMT
Server: nginx
Response headers from the localhost
Access-Control-Allow-Methods: POST, GET, PUT, DELETE
Access-Control-Allow-Origin: *
Connection: Keep-Alive
Content-Type: image/png
Date: Fri, 31 Jul 2020 03:53:10 GMT
Keep-Alive: timeout=120, max=1000
Server: Apache
Transfer-Encoding: chunked
X-Xdebug-Profile-Filename: D:\traces\cachegrind.out.13336
When an ajax request is made either it takes from the browser cache or from server based on the headers set.
But i want to detect if the response data is taken from browser cache or from the server.
I am using jquery ajax function.
What i have done is i am getting the response headers from server
Date: Tue, 17 Jun 2014 10:35:31 GMT
Server: Apache/2.2.15 (CentOS)
Connection: close
Content-Type: text/html; charset=UTF-8
X-Powered-By: PHP/5.5.8
Transfer-Encoding: chunked
Expires: Tue, 17 Jun 2014 10:36:32 GMT
and from the browser cache before expiry i get this
Date: Tue, 17 Jun 2014 10:35:31 GMT
Server: Apache/2.2.15 (CentOS)
Content-Type: text/html; charset=UTF-8
X-Powered-By: PHP/5.5.8
Expires: Tue, 17 Jun 2014 10:36:32 GMT
Basically i look for Transfer-Encoding and decide whether its from cache or server. But i doubt whether it is compatible across browsers.
is their any other method that i identify the response data is from cache or server?
I am setting this with htaccess. I know it's being set properly because if I set another header:
Header set Access-Control-Allow-Origin2: *
Then chrome does see this. As soon as I remove the 2 however, chrome just completely ignores it. If I make my file a PHP file and put this in it:
<?php header("Access-Control-Allow-Origin: *"); ?>
Then it works.
Here are the response headers as reported by Chrome of the .htaccess method which I need to work and which does not:
HTTP/1.1 304 Not Modified
Date: Sun, 30 Mar 2014 00:13:06 GMT
Server: Apache/2.2.22 (Ubuntu)
Connection: Keep-Alive
Keep-Alive: timeout=5, max=100
ETag: "208f3-178a2-4f5c4f119cd34"
Vary: Accept-Encoding
Here are the response headers as reported by Chrome from the PHP method which for some reason does work:
HTTP/1.1 200 OK
Date: Sun, 30 Mar 2014 00:13:09 GMT
Server: Apache/2.2.22 (Ubuntu)
X-Powered-By: PHP/5.3.10-1ubuntu3.10
Access-Control-Allow-Origin: *
Vary: Accept-Encoding
Content-Encoding: gzip
Content-Length: 23
Keep-Alive: timeout=5, max=99
Connection: Keep-Alive
Content-Type: text/html
Again, I know the htaccess is setting the header, even if I go to an online service that checks reponse headers, I see this back:
HTTP/1.1 200 OK
Date: Sun, 30 Mar 2014 00:18:14 GMT
Server: Apache/2.2.22 (Ubuntu)
Last-Modified: Sat, 29 Mar 2014 20:48:34 GMT
ETag: "208f3-178a2-4f5c4f119cd34"
Accept-Ranges: bytes
Vary: Accept-Encoding
Content-Encoding: gzip
Access-Control-Allow-Origin: *
Content-Length: 33393
Content-Type: application/javascript
calling a .html on my website directly the header will be:
HTTP/1.1 200 OK
Date: Tue, 07 May 2013 14:53:30 GMT
Server: Apache
Last-Modified: Tue, 24 Aug 2012 21:51:42 GMT
ETag: "1431a086-1e01-78e98c5498f1c"
Accept-Ranges: bytes
Content-Length: 7681
Vary: Accept-Encoding
Content-Type: text/html
now the request is forwarded through a php script like
(- the use of the php script here is only to filter some words from the html before delivering it by a regex and to add a footer to every page)
and the header looks like:
HTTP/1.1 200 OK
Date: Tue, 07 May 2013 14:52:50 GMT
Server: Apache
Vary: User-Agent,Accept-Encoding
Content-Type: text/html
Question: How to keep "Last-Modified: ..." and "ETag: ..." ?
Thanks=)
If I run an audit on my sites with Google Chrome, I get this message in the Leverage browser caching section:
The following resources are missing a
cache expiration. Resources that do
not specify an expiration may not be
cached by browsers:
A list of all the pictures follows. I get a similar notice in Leverage proxy caching:
Consider adding a "Cache-Control:
public" header to the following
resources:
Apart from pictures, I also get a notice about HTML, CSS and JavaScript files:
The following resources are explicitly
non-cacheable. Consider making them
cacheable if possible:
Its funny because I've worked hard to cache all static contents (except for pictures, where I just left Apache's default settings). Firefox does indeed store all these items in cache.
Is there anything I should improve in my HTTP headers?
Here's the complete header set of some items as loaded after removing the browser caché. Pictures use default settings I didn't really check before, the rest should be cachéd for three hours. I can set headers with both .htaccess and PHP.
PNG
HTTP/1.1 200 OK
Date: Sat, 31 Jul 2010 12:46:14 GMT
Server: Apache
Last-Modified: Thu, 18 Mar 2010 21:40:54 GMT
Etag: "c48024-230-4821a15d6c580"
Accept-Ranges: bytes
Content-Length: 560
Keep-Alive: timeout=4
Connection: Keep-Alive
Content-Type: image/png
HTML
HTTP/1.1 200 OK
Date: Sat, 31 Jul 2010 12:46:13 GMT
Server: Apache
X-Powered-By: PHP/5.2.11
Expires: Sat, 31 Jul 2010 15:46:13 GMT
Cache-Control: max-age=10800, s-maxage=10800, must-revalidate, proxy-revalidate
Content-Encoding: gzip
Vary: Accept-Encoding
Last-Modified: Wed, 24 Mar 2010 20:30:36 GMT
Keep-Alive: timeout=4
Connection: Keep-Alive
Transfer-Encoding: chunked
Content-Type: text/html; charset=ISO-8859-15
CSS
HTTP/1.1 200 OK
Date: Sat, 31 Jul 2010 12:48:21 GMT
Server: Apache
X-Powered-By: PHP/5.2.11
Expires: Sat, 31 Jul 2010 15:48:21 GMT
Cache-Control: max-age=10800, s-maxage=10800, must-revalidate, proxy-revalidate
Content-Encoding: gzip
Vary: Accept-Encoding
Last-Modified: Thu, 18 Mar 2010 21:40:12 GMT
Keep-Alive: timeout=4
Connection: Keep-Alive
Transfer-Encoding: chunked
Content-Type: text/css
JavaScript
HTTP/1.1 200 OK
Date: Sat, 31 Jul 2010 12:48:21 GMT
Server: Apache
X-Powered-By: PHP/5.2.11
Expires: Sat, 31 Jul 2010 15:48:21 GMT
Cache-Control: max-age=10800, s-maxage=10800, must-revalidate, proxy-revalidate
Content-Encoding: gzip
Vary: Accept-Encoding
Last-Modified: Thu, 18 Mar 2010 21:40:12 GMT
Keep-Alive: timeout=4
Connection: Keep-Alive
Transfer-Encoding: chunked
Content-Type: application/x-javascript
Update
I've tested Jumby's suggestion and set my CSS's expire to 1 year:
Cache-Control:max-age=31536000, s-maxage=31536000, must-revalidate, proxy-revalidate
Connection:Keep-Alive
Content-Encoding:gzip
Content-Length:4198
Content-Type:text/css
Date:Mon, 02 Aug 2010 20:48:56 GMT
Expires:Tue, 02 Aug 2011 20:48:56 GMT
Keep-Alive:timeout=5, max=99
Last-Modified:Thu, 18 Mar 2010 20:40:12 GMT
Server:Apache/2.2.14 (Win32) PHP/5.3.1
Vary:Accept-Encoding
X-Powered-By:PHP/5.3.1
However, Chrome still claims "explicitly non-cacheable".
3 hour expiry might not be enough "time" for the yslow/page speed stuff and they might complain about it. I have seen this with static content on my sites with 4 hour expiration & yslow (havent tried with google's stuff).
Most of those want versioned static content with LONG expire times (like 1 year); see here
The problem is the "must-revalidate" part of your cache-control directive. Get rid of that, and you should be good to go.
I just got a similar issue, I discovered the very same setup and code produces a chrome audit warning when trying on my test server at 127.0.0.1, but not on the real server with a real DNS name.