Question

À l'heure actuelle, j'essaie de servir les fichiers CSS et JS à partir d'un serveur qui ne me permet pas d'activer mod_gzip ou mod_deflate . J'ai donc écrit un petit script PHP à compresser avec GZIP et à retourner à l'utilisateur.

Exemple de code:

$filename = "style.css";

if (!file_exists($filename) || !($info = stat($filename))) {
  header("HTTP/1.1 404 Not Found");
  die();
}

header("Date: ".gmdate("D, j M Y H:i:s e", time()));
header("Cache-Control: max-age=2592000");
header("Last-Modified: ".gmdate("D, j M Y H:i:s e", $info['mtime']));
header("Etag: ".sprintf("\"%x-%x-%x\"", $info['ino'], $info['size'], $info['mtime']));
header("Accept-Ranges: bytes");
header("Cache-Control: Expires ".gmdate("D, j M Y H:i:s e", $info['mtime']+2592000));
header("Content-Type: text/html");

ob_start("ob_gzhandler");
echo file_get_contents($filename);
ob_end_flush();

J'ai deux problèmes en ce moment. La première est que je ne parviens pas à déterminer la taille résultante du fichier compressé pour informer le navigateur de la longueur du contenu. Normalement, je voudrais inclure cette ligne:

header("Content-Length: ".$info["size"]);

Mais si je le fais, le navigateur se bloque en essayant d'attendre plus de données. Existe-t-il un moyen de calculer la taille totale? Ou devrais-je ignorer cette directive d'en-tête.

L’autre problème est que, chaque fois que je visualise ce fichier PHP dans Firefox, il essaie de me faire télécharger le résultat. Dans Chrome, il l’affiche comme je l’espérais. Des suggestions?

Modifier: Grâce à SoapBox, j'ai remplacé la fin du code par ceci:

header("Content-Encoding: gzip");
$compressed = gzencode(file_get_contents($filename), 5);
header("Content-Length: ".strlen($compressed));
die($compressed);

Cela fonctionne très bien pour la longueur du contenu! Mais je demande toujours à Firefox de télécharger le fichier au lieu de l'afficher. : (

Modifier à nouveau: voici le code de fin de code modifié, gracieuseté de Cletus.

// Start buffered output
ob_start();
// Check for gzip capability
if (stripos(

À l'heure actuelle, j'essaie de servir les fichiers CSS et JS à partir d'un serveur qui ne me permet pas d'activer mod_gzip ou mod_deflate . J'ai donc écrit un petit script PHP à compresser avec GZIP et à retourner à l'utilisateur.

Exemple de code:

$filename = "style.css";

if (!file_exists($filename) || !($info = stat($filename))) {
  header("HTTP/1.1 404 Not Found");
  die();
}

header("Date: ".gmdate("D, j M Y H:i:s e", time()));
header("Cache-Control: max-age=2592000");
header("Last-Modified: ".gmdate("D, j M Y H:i:s e", $info['mtime']));
header("Etag: ".sprintf("\"%x-%x-%x\"", $info['ino'], $info['size'], $info['mtime']));
header("Accept-Ranges: bytes");
header("Cache-Control: Expires ".gmdate("D, j M Y H:i:s e", $info['mtime']+2592000));
header("Content-Type: text/html");

ob_start("ob_gzhandler");
echo file_get_contents($filename);
ob_end_flush();

J'ai deux problèmes en ce moment. La première est que je ne parviens pas à déterminer la taille résultante du fichier compressé pour informer le navigateur de la longueur du contenu. Normalement, je voudrais inclure cette ligne:

header("Content-Length: ".$info["size"]);

Mais si je le fais, le navigateur se bloque en essayant d'attendre plus de données. Existe-t-il un moyen de calculer la taille totale? Ou devrais-je ignorer cette directive d'en-tête.

L’autre problème est que, chaque fois que je visualise ce fichier PHP dans Firefox, il essaie de me faire télécharger le résultat. Dans Chrome, il l’affiche comme je l’espérais. Des suggestions?

Modifier: Grâce à SoapBox, j'ai remplacé la fin du code par ceci:

header("Content-Encoding: gzip");
$compressed = gzencode(file_get_contents($filename), 5);
header("Content-Length: ".strlen($compressed));
die($compressed);

Cela fonctionne très bien pour la longueur du contenu! Mais je demande toujours à Firefox de télécharger le fichier au lieu de l'afficher. : (

Modifier à nouveau: voici le code de fin de code modifié, gracieuseté de Cletus.

<*>

Je vais poser une nouvelle question pour savoir pourquoi Firefox continue de chercher à télécharger le fichier.

SERVER['HTTP_ACCEPT_ENCODING'], "gzip") !== false) { ob_start("ob_gzhandler"); echo file_get_contents($filename); ob_end_flush(); } else echo file_get_contents($filename); // Write the content length header('Content-Length: '.ob_get_length()); ob_end_flush();

Je vais poser une nouvelle question pour savoir pourquoi Firefox continue de chercher à télécharger le fichier.

Était-ce utile?

La solution

Le problème ici est que pour connaître la longueur du contenu, vous devez savoir si le client prend en charge le codage gzip et si vous avez délégué cette décision à l'aide de ob_gzhandler. De en-têtes HTTP :

ob_start();
ob_start('ob_gzhandler');

  ... output the page content...

ob_end_flush();  // The ob_gzhandler one

header('Content-Length: '.ob_get_length());

ob_end_flush();  // The main one

Version complète:

$filename = "style.css";

if (!file_exists($filename) || !($info = stat($filename))) {
  header("HTTP/1.1 404 Not Found");
  die();
}

header("Date: ".gmdate("D, j M Y H:i:s e", time()));
header("Cache-Control: max-age=2592000");
header("Last-Modified: ".gmdate("D, j M Y H:i:s e", $info['mtime']));
header("ETag: ".sprintf("\"%x-%x-%x\"", $info['ino'], $info['size'], $info['mtime']));
header("Accept-Ranges: bytes");
header("Expires: ".gmdate("D, j M Y H:i:s e", $info['mtime']+2592000));
header("Content-Type: text/css"); // note: this was text/html for some reason?

ob_start();
ob_start("ob_gzhandler");
echo file_get_contents($filename);
ob_end_flush();
header('Content-Length: '.ob_get_length());
ob_end_flush();

C'est beaucoup meilleur que de s'attaquer vous-même au problème d'encodage gzip.

Autres conseils

Vous devez d’abord faire tout le gzip et mesurer le résultat (soit en conservant le contenu en mémoire, soit en l’écrivant sur le disque au fur et à mesure que vous compressez puis en statuant le fichier gzip), puis écrivez l’en-tête Content-Length, puis envoyer le contenu du fichier.

Ou utilisez le l'encodage de transfert en bloc .

Pour résoudre votre problème avec Firefox, je pense que vous devez inclure en-tête ("Content-Encoding: gzip"); afin que le navigateur sache décompresser le contenu.

En ce qui concerne la longueur du contenu, vous pouvez essayer de laisser cette valeur désactivée ou de trouver un moyen d'utiliser "Transférer-Encodage: chunked". (Vous ne pouvez pas envoyer cet en-tête, vous devez formater les données spécialement pour cela). Il est possible que ob_end_flush active automatiquement le fractionnement.

Je vous recommande d’obtenir Wireshark, de capturer ce que votre script php envoie et de le comparer à un serveur qui se comporte correctement pour voir quels en-têtes, etc. sont manquants.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top