Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

ETag header does not return 304

I'm working currently on REST API. I wanted to check if HTTP cache is working fine, but unfortunatelly I doesn't work at all. No matter what I do, it always return HTTP code 200 while it should return 304 from what I know.

Here is my PHP code:

public function getList()
{
    $this->addHeaders(array(
        'Cache-Control' => 'public, must-revalidate, max-age=120',
        'eTag' => 'xyz123',
    ));

    $array = array(
        'foo' => 'bar',
        'nested' => array(
            'lorem' => 'ipsum',
            'dolor' => 'sit amet'
        )
    );

    $this->addHeader('Content-Length', strlen(json_encode($array, true)));

    return new JsonModel($array);
}

Response/Request

enter image description here

ETag doesn't change, so requests except first one should be served from cache. Am I wrong?

I was following these 2 articles:

  • https://developer.mozilla.org/en-US/docs/Web/HTTP/Caching
  • https://developers.google.com/web/fundamentals/performance/optimizing-content-efficiency/http-caching?hl=en

I also checked with weak validator- Last-Modified but I got same problem. Browser sends correct header in Request, but I still get 200 in response

like image 344
user1409508 Avatar asked Nov 08 '16 14:11

user1409508


2 Answers

ETag requires the server to send a 304 response back in order to trigger loading from the Cache.

In a time based cache:

  1. Client makes initial request, caches the response for a determined time
  2. In subsequent requests, if the resource is in the cache then it is used without contacting the server for that resource

In an ETag based cache:

  1. Client makes initial request, caches the response for a determined time along with the ETag from the server for that resource
  2. In subsequent requests, if the resource is in the cache then the ETag is included in a new request to the server as the If-None-Match field.
  3. The server checks the If-None-Match header and if it matches the content on the server, sends a 304 not modified which instructs the client cache to use it's local copy. If the ETag is different, then the server returns the resource as normal.

To make your code work, you need to check for the presence of the If-None-Match header in the PHP:

If(isset($_SERVER['HTTP_IF_NONE_MATCH']) && $_SERVER['HTTP_IF_NONE_MATCH'] == 'xyz123') {
    header("HTTP/1.1 304 Not Modified");
    exit();
}
like image 141
Steve E. Avatar answered Sep 30 '22 05:09

Steve E.


Your client is sending the Cache-Control header with a value of max-age=0. This indicates to the server that the client requests a fresh response and the server sends an HTTP 200 status code.

The Cache-Control header sent by the client is usually the result of using the developer tools in the browser and not disabling the "Disable caching" option.

like image 27
Digitalkapitaen Avatar answered Sep 30 '22 06:09

Digitalkapitaen