2012-07-16 3 views
1

J'utilise la bibliothèque tonic.php (http://peej.github.com/tonic/) pour créer mes ressources REST. Les données sont très stables et il serait préférable d'avoir de longs temps d'antémémoire. Je mets les en-têtes de cache (en utilisant la bibliothèque tonic.php):Comment mettre en cache différents formats/représentations de ressources REST?

$lastModified = gmdate('D, d M Y H:i:s', $_SERVER['REQUEST_TIME']) . ' GMT';      
$expires = gmdate('D, d M Y H:i:s', ($_SERVER['REQUEST_TIME'] + $httpCacheDuration)) . ' GMT'; 
$response->addHeader('Cache-Control', 'public,max-age='.$httpCacheDuration.',must-revalidate');      
$response->addHeader('Expires', $expires); 
$response->addHeader('Last-Modified', $lastModified); 

Le problème est que lorsque html est demandé un appel cURL est fait à une page php et html retourné est placé dans le corps de la réponse:

Cette page retournée obtient alors les données réelles par un appel AJAX à la même ressource mais avec l'en-tête accepter de "application/json" au lieu de "text/html". L'appel AJAX est fait avec jquery et si je mets

cache: true 

dans jquery $ .ajax un appel à ma ressource avec Accept: text/html affichera simplement les données en JSON au lieu de la page Web (Firefox) ou lancer une erreur (IE8). code:

switch ($format) { 

    case 'html': 

     $response->addHeader('Content-type', 'text/html'); 
     $lastModified = gmdate('D, d M Y H:i:s', $_SERVER['REQUEST_TIME']) . ' GMT';      
     $expires = gmdate('D, d M Y H:i:s', ($_SERVER['REQUEST_TIME'] + $httpCacheDuration)) . ' GMT';              
     $response->addHeader('Cache-Control', 'public,max-age='.$httpCacheDuration.',must-revalidate');      
     $response->addHeader('Expires', $expires); 
     $response->addHeader('Last-Modified', $lastModified); 
     $ch = curl_init(); 
     curl_setopt($ch, CURLOPT_COOKIE, $strCookie); 
     curl_setopt($ch, CURLOPT_URL, url . '?identifier=' . $identifier); 
     curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); 

     $html = curl_exec($ch);   
     curl_close($ch); 
     $response->body = $html; 
     return $response; 
     break; 

    case 'json': 

     $result = DataManager::get($identifier); 
     if (empty($result)) { 
      $response->code = Response::NOTFOUND; 
      return $response; 
     } 

     $lastModified = gmdate('D, d M Y H:i:s', $_SERVER['REQUEST_TIME']) . ' GMT';      
     $expires = gmdate('D, d M Y H:i:s', ($_SERVER['REQUEST_TIME'] + $httpCacheDuration)) . ' GMT';              
     $response->addHeader('Cache-Control', 'public,max-age='.$httpCacheDuration.',must-revalidate');      
     $response->addHeader('Expires', $expires); 
     $response->addHeader('Last-Modified', $lastModified); 
     $response->addHeader('Content-type', 'application/json'); 
     $response->code = Response::OK; 
     $response->body = json_encode($result); 
     return $response; 
     break; 

    // we don't have a suitable format, so do a 406 response instead 
    default: 
     $response->code = Response::NOTACCEPTABLE; 
     $response->addHeader('Content-type', 'text/plain'); 
     $response->body = getErrorPage(Response::NOTACCEPTABLE); 
     return $response; 
     break; 
} 

Ajout

$response->addHeader('Vary', 'Accept'); 

fait fonctionner. Cependant, le json n'est jamais mis en cache ce qui conduit au même comportement que la mise en cache: false dans Jquery ajax call.

Comment est-il possible de mettre en cache les 2 représentations différentes et d'afficher le navigateur approprié pour l'en-tête d'acceptation demandé?

+1

que diriez-vous si vous changez l'URL? Si je comprends votre problème, le cache du navigateur ne distingue pas le contenu basé sur l'en-tête Accepter dans la demande. Si vous ajoutez '.json' à l'URL du paquet JSON, le navigateur pourra mettre en cache en fonction de l'URL. – Cheeso

+0

merci. cela a fait du travail aussi vous vous demandez quel est le point de varier: Accepter est si cela ne fonctionne pas et il faut utiliser "contournements hacky". –

+0

Deviner ... peut-être "Varier" est l'une des pièces les moins matures de la pile. – Cheeso

Répondre

0

réponse est en commentaire 1:

diriez-vous si vous variez l'URL? Si je comprends votre problème, le cache du navigateur ne distingue pas le contenu basé sur l'en-tête Accepter dans la demande. Si vous ajoutez .json à l'URL du paquet JSON, le navigateur pourra mettre en cache en fonction de l'URL.

Questions connexes