Использование htaccess для автоматического управления версиями: htaccess regex Правило перезаписи не выбирает шаблон - PullRequest
8 голосов
/ 20 марта 2011

Используя предложение в ответе на этот вопрос , а также эту статью , которая предлагает почти идентичное решение, я пытался настроить htaccess для обработки автоверсииправила для моих файлов js и css.

Причина, по которой я хочу это сделать, заключается в том, что я довольно часто меняю их, но все же хочу, чтобы они кэшировались браузерами в течение агрессивно длительных периодов, без необходимости вручную вводитьновый номер версии каждый раз, когда они меняются.

Используемый метод прост: (1) функция добавляет номер версии к файлам, используя дату, в которую они были изменены, по шаблону [filename].[version_number].[suffix], поэтому style.css, например, станет, скажем, style.1300638388.css;(2) используя php, версионный номер включается в объявление таблицы стилей для страниц моего сайта, и он предоставляется клиентским браузерам, которые будут запрашивать новую копию, если версионное имя файла отличается от того, которое они кэшировали;(3) RewriteRule в .htaccess с использованием mod_rewrite перезаписывает версионный номер, возвращает его исходное значение и передает обновленный файл.

Код, который я использую на каждом из этих трех этапов, приведен ниже.Я тестирую это в таблице стилей в песочнице моего блога на http://edge.donaldjenkins.net/

1.В файле WordPress functions.php

// 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);
}

2.В разделе <head> моего блога файлы

<!-- Stylesheets  -->
<link rel="stylesheet" href="<?=auto_version('/path/to/style.css')?>" />

3.В файле .htaccess

# 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

При описанной выше настройке страницы отображаются без какого-либо форматирования, и исходный код сгенерированной страницы показывает, что таблица стилей упоминается как номер версии, что, конечно, несуществуют на сервере.

Это может означать, что функция правильно меняет имя таблицы стилей, но по какой-то причине шаблон регулярного выражения в RewriteRule в .htaccess не перехватывает имя файла и не переписывает его,На самом деле, он даже не ловит его, если я изменяю его на ^style.1300638388.css$ style.css [L].

Я пробовал несколько шаблонов, но безрезультатно, но, должно быть, упустил что-то довольно простое.

mod_rewrite включен на сервере и работает без проблем для нескольких других экземпляров RewriteRule.

UPDATE

Единственный другой RewriteRule в файле .htaccess является стандартнымWordPress Правило переписывания довольно 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

ОБНОВЛЕНИЕ 2: РЕШЕНО

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>

Ответы [ 2 ]

3 голосов
/ 20 марта 2011

^ означает «начало строки», в данном случае это не «стиль», а /path/to/style.

Вы можете попробовать его с полным путем в регулярном выражении, иливозможно, загляните в RewriteBase.

обновленное решение Проблема в этом сценарии заключалась в том, что до рассматриваемого существовали другие RewriteRules, поэтому он никогда не достигал этого RewriteRule.Правильный порядок RewriteRules важен.

2 голосов
/ 20 сентября 2012

Спасибо за решение .htaccess. У меня были проблемы с файлами плагинов jQuery, которые включают свою собственную схему управления версиями в имя файла, как в jquery.NAME-OF-PLUGIN.1.1.1.js. Я рекомендую проанализировать время изменения файла с помощью [0-9]{10}, так что будет удален только десятизначный суффикс. Это все еще возможно для ошибок, если имя файла имеет десять цифр в конце, но это будет редкий случай.

# Allow versioning for js and css files

RewriteRule ^(.*)\.[0-9]{10}\.(css|js)$ $1.$2 [L] # Strip out the version number

# End Allow versioning for js and css files

Кроме того, 11 цифр в метке времени эпохи UNIX не нужно учитывать до субботы, 20 ноября 2286 г. 17:46:40 по Гринвичу.

...