Используя предложение в ответе на этот вопрос, а также эту статью, которая предлагает почти идентичное решение, я пытался настроить htaccess для обработки правила автоверсии для моих js и css файлов.
Причина, по которой я хочу это сделать, заключается в том, что я довольно часто меняю их, но все же хочу, чтобы они кэшировались браузерами в течение длительного времени, без необходимости вручную вводить новый номер версии при каждом изменении.
Используемый метод прост: (1) функция добавляет номер версии к файлам, используя дату их изменения, по шаблону [имя файла].[номер_версии].[суффикс]
, так что style.css
, например, станет, скажем, style.1300638388 .css
; (2) используя php, номер версии включается в объявление таблицы стилей для страниц моего сайта, и это передается клиентским браузерам, которые будут запрашивать свежую копию, если имя файла версии отличается от того, что они кэшировали; (3) правило RewriteRule в .htaccess с использованием mod_rewrite переписывает номер версии, возвращает его к исходному значению и передает обновленный файл.
Код, который я использую на каждом из этих трех этапов, приведен ниже. Я тестирую это на таблице стилей в песочнице версии моего блога на http://edge.donaldjenkins.net/
// Allows autoversioning of css and js files
/**
* Given a file, i.e. /css/base.css, replaces it with a string containing the
* file's mtime, i.e. /css/base.1221534296.css.
*
* @param $file The file to be loaded. Must be an absolute path (i.e.
* starting with slash).
*/
function auto_version($file)
{
if(strpos($file, '/') !== 0 || !file_exists($_SERVER['DOCUMENT_ROOT'] . $file))
return $file;
$mtime = filemtime($_SERVER['DOCUMENT_ROOT'] . $file);
return preg_replace('{\\.([^./]+)$}', ".$mtime.\$1", $file);
}
части файлов моего блога<!-- Stylesheets -->
<link rel="stylesheet" href="<?=auto_version('/path/to/style.css')?>" />
# Allow versioning for js and css files
RewriteEngine On
RewriteRule ^(.*)\.[\d]+\.(css|js)$ $1.$2 [L] # Strip out the version number
# End Allow versioning for js and css files
При описанной выше настройке страницы отображаются без какого-либо форматирования, а исходный код сгенерированной страницы показывает, что на таблицу стилей ссылается номер версии, который, конечно же, не существует на сервере.
Это говорит о том, что функция правильно изменяет имя таблицы стилей, но по какой-то причине шаблон regex в RewriteRule в .htaccess не перехватывает имя файла и не переписывает его. Фактически, он даже не перехватывает его, если я изменяю его на ^style.1300638388.css$ style.css [L]
.
Я пробовал несколько шаблонов, безрезультатно, но, должно быть, не хватает чего-то довольно базового.
mod_rewrite
включен на сервере и работает без проблем для нескольких других экземпляров RewriteRule.
UPDATE
Единственное другое правило RewriteRule в файле .htaccess
- это стандартное правило перезаписи WordPress pretty url. Я сомневаюсь, что оно мешает этому, хотя, очевидно, я не могу легко протестировать без правила WordPress, так как это полностью нарушит генерацию страниц:
# BEGIN WordPress
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteBase /
RewriteRule ^index\.php$ - [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /index.php [L]
</IfModule>
# END WordPress
UPDATE 2: SOLVED
CharlesLeaf в комментарии ниже указал, что поскольку правило WordPress было до правила версионирования, последнее не будет выполняться. Это действительно было причиной и позволило мне ответить на вопрос, сгруппировав эти два правила следующим образом:
<IfModule mod_rewrite.c>
# Allow versioning for js and css files
RewriteEngine On
RewriteRule ^(.*)\.[\d]+\.(css|js)$ $1.$2 [L] # Strip out the version number
# End Allow versioning for js and css files
# BEGIN WordPress
RewriteBase /
RewriteRule ^index\.php$ - [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /index.php
# END WordPress
</IfModule>