2010-02-05 2 views
11

En utilisant PHP comment puis-je tester avec précision qu'un site Web distant prend en charge l'en-tête HTTP "If-Modified-Since". D'après ce que j'ai lu, si le fichier distant que vous avez modifié a été modifié depuis la date spécifiée dans la demande d'en-tête, il doit renvoyer un état 200 OK. S'il n'a pas été modifié, il doit retourner un 304 non modifié.Comment tester pour le support d'en-tête HTTP "If-Modified-Since"

Par conséquent, ma question est, et si le serveur ne prend pas en charge "If-Modified-Since" mais renvoie quand même un 200 OK?

Il existe quelques outils qui vérifient si votre site Web prend en charge "If-Modified-Since", donc je suppose que je demande comment ils fonctionnent.

Edit:

J'ai effectué quelques tests en utilisant Curl, l'envoi de ce qui suit:

curl_setopt($ch, CURLOPT_HTTPHEADER, array("If-Modified-Since: ".gmdate('D, d M Y H:i:s \G\M\T',time()+60*60*60*60))); 
curl_setopt($ch, CURLOPT_URL, $url); 
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); 
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true); 
curl_setopt($ch, CURLOPT_MAXREDIRS, 5); 
curl_setopt($ch, CURLOPT_HEADER, true); 
curl_setopt($ch, CURLOPT_NOBODY, true); 
curl_setopt($ch, CURLOPT_AUTOREFERER, true); 
curl_setopt($ch, CURLOPT_FORBID_REUSE, true); 
curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 4); 
curl_setopt($ch, CURLOPT_TIMEOUT, 4); 

c'est-à-dire une date dans le futur google.com revient;

HTTP/1.0 304 Not Modified 
Date: Fri, 05 Feb 2010 16:11:54 GMT 
Server: gws 
X-XSS-Protection: 0 
X-Cache: MISS from . 
Via: 1.0 .:80 (squid) 
Connection: close 

et si j'envoie;

curl_setopt($ch, CURLOPT_HTTPHEADER, array("If-Modified-Since: ".gmdate('D, d M Y H:i:s \G\M\T',time()-60*60*60*60))); 
curl_setopt($ch, CURLOPT_URL, $url); 
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); 
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true); 
curl_setopt($ch, CURLOPT_MAXREDIRS, 5); 
curl_setopt($ch, CURLOPT_HEADER, true); 
curl_setopt($ch, CURLOPT_NOBODY, true); 
curl_setopt($ch, CURLOPT_AUTOREFERER, true); 
curl_setopt($ch, CURLOPT_FORBID_REUSE, true); 
curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 4); 
curl_setopt($ch, CURLOPT_TIMEOUT, 4); 

En d'autres termes, date google.com renvoie;

HTTP/1.0 200 OK 
Date: Fri, 05 Feb 2010 16:09:12 GMT 
Expires: -1 
Cache-Control: private, max-age=0 
Content-Type: text/html; charset=ISO-8859-1 
Server: gws 
X-XSS-Protection: 0 
X-Cache: MISS from . 
Via: 1.0 .:80 (squid) 
Connection: close 

Si j'envoie alors les deux à bbc.co.uk (qui ne le supporte pas);

Le futur revient;

HTTP/1.1 200 OK 
Date: Fri, 05 Feb 2010 16:12:51 GMT 
Server: Apache 
Set-Cookie: BBC-UID=84bb66bc648318e367bdca3ad1d48cf627005b54f090f211a2182074b4ed92c40ForbSoft%20Web%20Diagnostics%20%28URL%20Validator%29; expires=Tue, 04-Feb-14 16:12:51 GMT; path=/; domain=bbc.co.uk; 
Accept-Ranges: bytes 
Cache-Control: max-age=0 
Expires: Fri, 05 Feb 2010 16:12:51 GMT 
Pragma: no-cache 
Content-Length: 111677 
Content-Type: text/html 

La date dans le passé est retournée;

HTTP/1.1 200 OK 
Date: Fri, 05 Feb 2010 16:14:01 GMT 
Server: Apache 
Set-Cookie: BBC-UID=841b66ec44232cd91e81e88a014a3c5e50ed4e20c0e07174c4ff59675cd2fa210ForbSoft%20Web%20Diagnostics%20%28URL%20Validator%29; expires=Tue, 04-Feb-14 16:14:01 GMT; path=/; domain=bbc.co.uk; 
Accept-Ranges: bytes 
Cache-Control: max-age=0 
Expires: Fri, 05 Feb 2010 16:14:01 GMT 
Pragma: no-cache 
Content-Length: 111672 
Content-Type: text/html 

Donc ma question est toujours là.

+0

S'il vous plaît afficher les boucles que vous utilisez les commandes, je teste la ligne de commande et tout ce que je reçois est 200s, peu importe ce que j'envoie tête – adamJLev

+0

Si le serveur ne supporte pas * If-Modified-Since * mais retourne toujours le code d'état 200, alors c'est comme si vous aviez envoyé la requête sans * If-Modified-Since * et le serveur répond avec le code d'état 200. Il n'y a pas de différence. 200 est 200, "La demande a réussi." – Gumbo

+0

@Infinity - J'ai ajouté les commandes/options curl dans mon post original ci-dessus. –

Répondre

6

J'ai effectué quelques tests sur ceci et il semble fonctionner comme suit;

Si vous envoyez un en-tête If-Modified-Since avec une date qui est dans le passé (5 minutes avant l'heure actuelle devrait le faire), des sites tels que google.com, w3.org, mattcutts.com retourne un en-tête "HTTP/1.1 304 Not Modified". Des sites tels que yahoo.com, bbc.co.uk et stackoverflow.com retournent toujours un "HTTP/1.1 200 OK". L'en-tête "Last-Modified" a rien à faire avec "If-Modified-Since" parce que le point entier de renvoyer un en-tête "HTTP/1.1 304 Not Modified" est que vous ne devez pas envoyer le corps avec (économiser ainsi la bande passante - qui est le point entier derrière cela). Par conséquent, la réponse à ma question est que si un site ne renvoie pas un en-tête "HTTP/1.1 304 non modifié" lorsque vous envoyez un en-tête "If-Modified-Since 5 mins ago", le site doesn ' t supporte correctement la requête "If-Modified-Since".

Si je me trompe, veuillez le dire et fournir des tests à montrer. J'ai oublié d'ajouter qu'un bon test consiste à faire une requête HEAD normale au domaine (par exemple w3.org), à saisir la date "Last Modified" et à faire une autre requête avec "If-Modified" -Depuis:". Cela vérifiera que les deux valeurs "Dernière modification" et "Si-Modifié depuis" sont prises en charge. S'il vous plaît noter: juste parce que le serveur renvoie une date "Dernière modification" ne signifie pas qu'il prend en charge "If-Modified-Since"

+0

Je suis content que vous ayez trouvé une solution, mais je l'ai mentionné dans ma réponse comme un moyen plus «pratique» de déduire la capacité du serveur, par rapport à l'approche d'en-tête plus «théorique». Citant moi-même: "Peut-être que vous pouvez simplement faire deux demandes, l'une suivie par une autre, en envoyant un en-tête If-Modified-Since, puis vérifier si la deuxième demande est un 304 ou un 200." – adamJLev

+0

@Infinity - Si vous lisez ma réponse, vous verrez que le tien aboie sur un arbre différent, mais je peux voir ce que vous entendez par l'approche "pratique", qui est finalement l'endroit où je l'ai pris. –

+0

Tout d'abord, chaque navigateur gère ce concept différemment. Deuxièmement, en utilisant Chrome v22, le serveur doit envoyer un en-tête «Last-Modified» pour que Chrome envoie un en-tête «If-Modified-Since».Cette réponse n'est pas correcte. –

5

Si l'entité renvoie un en-tête "Last-Modified", elle le prend en charge. Cela a vraiment du sens.

Plus d'info: http://httpd.apache.org/docs/2.2/caching.html (Guide sommaire aux demandes conditionnelles)

Il est évident que les pages statiques/fichiers aura cet en-tête. Avec le contenu dynamique (asp, php, etc.), il n'y a aucun moyen de connaître les en-têtes (à moins que les gestionnaires de sites mettent en cache manuellement, par exemple like this) et l'entité peut ou non prendre en charge If-Modified-Since.

Peut-être que vous pouvez juste faire deux demandes, un suivi d'une autre, l'envoi d'un If-Modified-Since, puis vérifiez si la deuxième demande est un 304 ou un 200

EDIT- hurikhan77 une relève note importante, et c'est que, par exemple tester la racine du site pour cette capacité, ne garantit pas que le reste du site ne supporte pas/ne supporte pas cela aussi.

+0

Oui, cela a du sens et merci beaucoup de m'avoir envoyé ce lien –

+0

Ce n'est pas tout à fait vrai: Remplacer "serveur" par "entité" et ça ira. – hurikhan77

1

en ce qui concerne la première réponse ci-dessus, je tiens à noter que les demandes conditionnelles ont autant de sens sur le contenu dynamique comme sur le contenu statique. Si le code qui génère le contenu dynamique sait que l'entité dorsale (par exemple l'élément de base de données) n'a pas changé, il doit envoyer un 304 lors d'une demande conditionnelle.

Jan

0

Ceci est un excellent outil. La même page propose d'autres outils aussi:

if-modified