2008-09-07 32 views
8

Apache 2を実行している共有ホストにいくつかのサイトがあります。ブラウザに配信されるHTML、CSS、Javascriptを圧縮したいと思います。ホストはmod_deflateとmod_gzipを無効にしているので、これらのオプションはありません。私はPHP5を自由に使えるので、gzipコンポーネントを使うことができます。mod_deflateとmod_gzipでHTML、CSS、JSを圧縮する最良の方法

私は現在、私の.htaccessファイルに次のように配置しています:ob_gzhandlerを

の出力ハンドラ

はphp_valueはしかし、これはのみHTMLを圧縮し、CSSやJSを残します。

すべてのページを変更することなく、CSSとJSの出力を透過的に圧縮する信頼できる方法はありますか?私はGoogleを検索し、いくつかのソリューションが提示されていますが、まだ動作させることはありません。誰もが知っている解決策を提案できれば、それは非常に感謝して受け取ります。

注意、The Definitive Post on Gzipping your CSS方法2は良い解決策のように見えますが、私はそれが働いて得ることができませんでした。誰かがこの方法で成功しましたか?

+0

ちょうど不思議なことに、なぜホスト企業はmod_deflateとmod_gzipを無効にしていますか?実際には、それらをオンにするのは彼らの興味です! – scunliffe

答えて

1

mod_rewriteであなたの運を試すことができます。

ローカル静的ファイル名を入力として使用するスクリプトを作成します。 $_SERVER['QUERY_STRING']を圧縮して出力します。多くのプロバイダーでは、を.htaccess個のファイルに設定することはできませんが、完全に無効にしてもかまいません。

を書き直す前にを書き換えていない場合は、おそらくthis oneのような初心者用ガイドをお勧めします。 このようにして、Apacheは静的ファイルのすべての要求をPHPスクリプトにリダイレクトできます。 style.cssはcompress.php?style.cssにリダイレクトされます。

いつもと同じ非常にあなたが受け入れる入力には慎重であるか、XSSあなたの手に悪用されている!私は何

+0

@macbirdie、この提案に対する多くのおかげです。このアプローチの例を提供したり、リンクしたりできますか?私はまた、そのようなスクリプトを確保するためのいくつかの一般的な技術を知ることに興味があります。 –

4

  • Iは、それぞれ、cssディレクトリ内jsとスタイルシートにスクリプトを配置します。 Apacheの設定で
  • 、私はそうのようなディレクティブを追加します。

    <?php 
        header("Content-type: text/javascript; charset: UTF-8"); 
    ?> 
    
  • ...とgzip-CS:jsディレクトリ内

    <Directory /data/www/path/to/some/site/js/> 
        AddHandler application/x-httpd-php .js 
        php_value auto_prepend_file gzip-js.php 
        php_flag zlib.output_compression On 
    </Directory> 
    <Directory /data/www/path/to/some/site/css/> 
        AddHandler application/x-httpd-php .css 
        php_value auto_prepend_file gzip-css.php 
        php_flag zlib.output_compression On 
    </Directory> 
    
  • gzipでjs.phpは、次のようになります。cssディレクトリ内のPHPは次のよ​​うになります。

    <?php 
        header("Content-type: text/css; charset: UTF-8"); 
    ?> 
    

は、これが最もエレガントな解決策ではないかもしれないが、それは最も確かにいくつかの変更を必要とし、うまく機能単純なものです。あなたは今までに何

+0

私はこれを試してみましたが、残念ながらそれを働かせることはできませんでした。提案どおりにディレクティブを追加すると、内部サーバーエラーが発生します。 –

1

、クライアント側でキャッシュに関する注意してください:

ブラウザは、帯域幅を試してみて、最小限に抑えるためにトリックのすべての並べ替えを行うと、それを行うためのHTTPプロトコルには多くの方法があり、すべてがあなたがローカルファイルを提供しているだけの場合は、apacheによって処理されます。

あなたがいない場合は、あなたの責任です

最新のすべてのブラウザでサポートされているETagとIf-Modified-Sinceの仕組みを見てください。サーバーに更新されたコンテンツを照会する最も堅牢な方法です。

$p = 'path/to/css/file' 
$i = stat($p); 
if ($_SERVER['HTTP_IF_MODIFIED_SINCE']){ 
    $imd = strtotime($_SERVER['HTTP_IF_MODIFIED_SINCE']); 
    if (($imd > 0) && ($imd >= $i['mtime'])){ 
     header('HTTP/1.0 304 Not Modified'); 
     header('Expires:'); 
     header('Cache-Control:'); 
     header('Last-Modified: '.date('r', $i['mtime'])); 
     exit; 
    } 
} 
header('Last-Modified: '.date('r', $i['mtime'])); 
header('Content-Type: text/css'); 
header('Content-Length: '.filesize($p)); 
header('Cache-Control:'); 
header('Pragma:'); 
header('Expires:'); 
readfile($p); 
:場合 - 変更 - ので、ヘッダーを使用してブラウザにCSSファイルを提供する

可能な方法は、この(空のヘッダがPHPはデフォルトごとに送信するすべての非キャッシングヘッダをオフにする)のようなものです

このコードでは、ブラウザが送信した日付以降にサーバー上の実際のファイルが変更されたかどうかを確認するために、ブラウザが送信するif-modified-since-headerを使用します。そうでない場合、ファイルが送信されます。そうでない場合は、304 Not Modifiedが返され、ブラウザはコンテンツ全体を再ダウンロードする必要はありません(十分に知的であれば、解析されたCSSもメモリ内に保持されます)。

サーバーが各コンテンツに一意のETagヘッダーを送信することを含む別の方法があります。クライアントは、If-None-Matchヘッダーを使用してそれを送り返します。これにより、サーバーは最後の変更日だけでなくコンテンツ自体も決定することができます。

これはコードを複雑にしているので、私はそれをやめました。 FF、IE、Opera(おそらくSafariも)は、Last-Modifiedヘッダーが添付されたコンテンツを受け取ったときにIf-Modified-Sinceヘッダーを送信するので、正常に動作します。

また、特定のバージョンのIE(またはJScript-Runtimeが使用する)は、のGZIP転送コンテンツに問題があることにも注意してください。

ああ。それが問題の一部ではないことは分かっていますが、一部のバージョンではAcrobatもそうです。私は、gzip転送エンコーディングでPDFを処理している間に、ケースとホワイトスクリーンのケースを持っていました。

+0

GZIPコンテンツのIE/JScriptに関するsrc/urlがありますか?私はgzipをサポートしていない古いバージョンのIE(IE6の前など)を思い出していますが、それは単に低速の圧縮されていないコンテンツを取得したことを意味します。まだIEに問題がある場合、私は確かに知りたいです! – scunliffe

+0

IEがgzipで転送された外部JSファイルを解析できない場合がありました。 Acrobatプラグインのいくつかのバージョン(現在でも)は、可能であると主張しても、圧縮を処理できません。 – pilif

7

遅れて申し訳ありません。私にとっては忙しい週です。

仮定:

  • .htaccessが圧縮されるcompress.php
  • 静的ファイルと同じファイルである私は、以下のディレクティブを設定するから私の解決策を開始したstaticサブディレクトリ

です。htaccessファイル:

RewriteEngine on 
RewriteRule ^static/.+\.(js|ico|gif|jpg|jpeg|png|css|swf)$ compress.php [NC] 

あなたのプロバイダがあなたが.htaccessファイルでmod_rewriteオプションを上書きすることを可能にすることを要求されます。 はその後compress.phpファイル自体は次のようになります。

<?php 

$basedir = realpath(dirname($_SERVER['SCRIPT_FILENAME'])); 
$file = realpath($basedir . $_SERVER["REQUEST_URI"]); 

if(!file_exists($file) && strpos($file, $basedir) === 0) { 
    header("HTTP/1.0 404 Not Found"); 
    print "File does not exist."; 
    exit(); 
} 

$components = split('\.', basename($file)); 
$extension = strtolower(array_pop($components)); 

switch($extension) 
{ 
    case 'css': 
     $mime = "text/css"; 
     break; 
    default: 
     $mime = "text/plain"; 
} 

header("Content-Type: " . $mime); 
readfile($file); 

もちろん、switch文に多くのMIMEタイプを追加する必要があります。私は解決策をpecl fileinfo拡張子や他の魔法のようなmimeタイプの検出ライブラリに依存させたくありませんでした。これは最も簡単な方法です。

スクリプトを安全にするために、私はファイルシステムの実際のパスへの変換を行い、ハッキングされた '../../../etc/passwd'やその他のシェルスクリプトファイルのパスは通過しません。

$basedir = realpath(dirname($_SERVER['SCRIPT_FILENAME'])); 
$file = realpath($basedir . $_SERVER["REQUEST_URI"]); 

スニペットです。私はかなり確信していますが、$ basedir以外の階層にあるほとんどのパスは、スクリプトに到達する前にApacheによって処理されます。

また、結果のパスがスクリプトのディレクトリツリー内にあるかどうかを確認します。 pilifが示唆しているように、キャッシュ制御用のヘッダーを追加してください。問題解決のための解決策が必要です。

+0

ありがとう、私はこれを行かせます。私は確かに、SOFに質問が更新されたときにあなたに知らせるための電子メールアラートを持っていたがっています。 –

+0

ねえ、これでどうやって使うの?私はcompress.phpとしてこれを保存正しいですか?インクルードを使用していますか? – Coughlin

+0

このスクリプトは、Apacheの書き換えルールによって実行され、URIパラメータとしてファイル名が与えられていることを前提としています。 – macbirdie

1

ユーザーがCSSおよびJavaScriptファイルを要求したときにgzippingするのではなく、あらかじめgzipできます。 Apacheが適切なヘッダーを提供する限り、あなたは金色です。

gzip -c styles.css > styles-gzip.css 

はしかしあなたのために働くワークフローのソートされない可能性がありますよう

はたとえば、Mac OS X上で、コマンドライン上のファイルをgzippingすることと同じくらい簡単です。

関連する問題