Порядок синтаксису mod_rewrite
mod_rewrite має деякі конкретні правила впорядкування, які впливають на обробку. Перш ніж щось робити, RewriteEngine On
директиву потрібно надати, оскільки це вмикає обробку mod_rewrite. Це повинно бути перед будь-якими іншими переписаними директивами.
RewriteCond
Попереднє RewriteRule
робить, що ОДНЕ правило підлягає умовному. Будь-які наступні RewriteRules будуть оброблятися так, ніби вони не підлягали умовам.
RewriteEngine On
RewriteCond %{HTTP_REFERER} ^https?://serverfault\.com(/|$)
RewriteRule $/blog/(.*)\.html $/blog/$1.sf.html
У цьому простому випадку, якщо HTTP-референт походить з serverfault.com, перенаправляйте запити блогу на спеціальні сторінки сервера за замовчуванням (ми просто такі особливі). Однак якщо вищевказаний блок мав додатковий рядок RewriteRule:
RewriteEngine On
RewriteCond %{HTTP_REFERER} ^https?://serverfault\.com(/|$)
RewriteRule $/blog/(.*)\.html $/blog/$1.sf.html
RewriteRule $/blog/(.*)\.jpg $/blog/$1.sf.jpg
Усі .jpg-файли переходитимуть на спеціальні серверні сторінки за замовчуванням, а не лише ті, на яких посилається референс, який вказує, що вони походять звідси. Очевидно, це не є метою написання цих правил. Це можна зробити за допомогою декількох правил RewriteCond:
RewriteEngine On
RewriteCond %{HTTP_REFERER} ^https?://serverfault\.com(/|$)
RewriteRule ^/blog/(.*)\.html /blog/$1.sf.html
RewriteCond %{HTTP_REFERER} ^https?://serverfault\.com(/|$)
RewriteRule ^/blog/(.*)\.jpg /blog/$1.sf.jpg
Але, мабуть, це слід зробити з синтаксисом заміни, що складніше.
RewriteEngine On
RewriteCond %{HTTP_REFERER} ^https?://serverfault\.com(/|$)
RewriteRule ^/blog/(.*)\.(html|jpg) /blog/$1.sf.$2
Складніша RewriteRule містить умови для обробки. Остання дужка (html|jpg)
вказує RewriteRule збігатися з будь-яким html
або jpg
, і представляти відповідне рядок як $ 2 у переписаному рядку. Це логічно ідентично попередньому блоку, з двома парами RewriteCond / RewriteRule, він просто робить це у двох рядках замість чотирьох.
Кілька рядків RewriteCond неявно підключені AND, і вони можуть бути явно ORE. Для обробки референсів як із ServerFault, так і з Super User (явний АБО):
RewriteEngine On
RewriteCond %{HTTP_REFERER} ^https?://serverfault\.com(/|$) [OR]
RewriteCond %{HTTP_REFERER} ^https?://superuser\.com(/|$)
RewriteRule ^/blog/(.*)\.(html|jpg) /blog/$1.sf.$2
Для обслуговування сторінок, на які посилаються ServerFault, із браузерами Chrome (неявне І):
RewriteEngine On
RewriteCond %{HTTP_REFERER} ^https?://serverfault\.com(/|$)
RewriteCond %{HTTP_USER_AGENT} ^Mozilla.*Chrome.*$
RewriteRule ^/blog/(.*)\.(html|jpg) /blog/$1.sf.$2
RewriteBase
також є специфічним для порядку, оскільки він визначає, як наступні RewriteRule
директиви обробляють їх обробку. Це дуже корисно у файлах .htaccess. Якщо використовується, це має бути першою директивою у розділі "RewriteEngine on" у файлі .htaccess. Візьмемо цей приклад:
RewriteEngine On
RewriteBase /blog
RewriteCond %{HTTP_REFERER} ^https?://serverfault\.com(/|$)
RewriteRule ^(.*)\.(html|jpg) $1.sf.$2
Це говорить mod_rewrite, що ця конкретна URL-адреса, якою вона зараз обробляється, надійшла за допомогою http://example.com/blog/ замість фізичного шляху до каталогу (/ home / $ Username / public_html / blog) і відповідно до цього ставитися. Через це, RewriteRule
вважає, що після URL-адреси "/ блогу" в URL-адресі починається рядок. Ось те саме написано двома різними способами. Один з RewriteBase, інший без:
RewriteEngine On
##Example 1: No RewriteBase##
RewriteCond %{HTTP_REFERER} ^https?://serverfault\.com(/|$)
RewriteRule /home/assdr/public_html/blog/(.*)\.(html|jpg) $1.sf.$2
##Example 2: With RewriteBase##
RewriteBase /blog
RewriteCond %{HTTP_REFERER} ^https?://serverfault\.com(/|$)
RewriteRule ^(.*)\.(html|jpg) $1.sf.$2
Як бачите, RewriteBase
дозволяє переписати правила для використання шляху веб- сайту до вмісту, а не до веб- сервера , що може зробити їх більш зрозумілими для тих, хто редагує такі файли. Крім того, вони можуть зробити директиви коротшими, що має естетичну привабливість.
Перепишіть синтаксис відповідності
Сам RewriteRule має складний синтаксис відповідності рядків. Я висвітлю прапори (такі речі, як [PT]) в іншому розділі. Оскільки сисадміни навчаються на прикладі частіше, ніж читаючи довідкову сторінку, я наведу приклади та поясню, що вони роблять.
RewriteRule ^/blog/(.*)$ /newblog/$1
.*
Конструкція відповідає будь-якому одному символу ( .
) нуль або більше разів ( *
). Закривши його в круглих дужках, він пропонує йому надати рядок, який відповідав змінній $ 1.
RewriteRule ^/blog/.*/(.*)$ /newblog/$1
У цьому випадку перший. * НЕ був укладений у пароні, тому не надається переписаному рядку. Це правило видаляє рівень каталогу на новому веб-сайті блогу. (/blog/2009/sample.html стає /newblog/sample.html).
RewriteRule ^/blog/(2008|2009)/(.*)$ /newblog/$2
У цьому випадку перший вираз у дужках створює групу, що відповідає. Це стає $ 1, який не потрібен і тому не використовується в переписаному рядку.
RewriteRule ^/blog/(2008|2009)/(.*)$ /newblog/$1/$2
У цьому випадку ми використовуємо $ 1 у переписаному рядку.
RewriteRule ^/blog/(20[0-9][0-9])/(.*)$ /newblog/$1/$2
У цьому правилі використовується спеціальний синтаксис дужок, який визначає діапазон символів . [0-9] відповідає цифрам від 0 до 9. Це конкретне правило стосується років з 2000 по 2099 роки.
RewriteRule ^/blog/(20[0-9]{2})/(.*)$ /newblog/$1/$2
Це робить те саме, що і попереднє правило, але частина {2} повідомляє йому, що два рази збігався з попереднім символом (дужкою в цьому випадку).
RewriteRule ^/blog/([0-9]{4})/([a-z]*)\.html /newblog/$1/$2.shtml
Цей випадок буде відповідати будь-якій малої літери у другому виразі, що відповідає, і зроби це для якомога більше символів. \.
Конструкція говорить це , щоб розглядати період як фактичний період, а не великий характер це в попередніх прикладах. Він зламається, якщо ім'я файлу має тире, хоча.
RewriteRule ^/blog/([0-9]{4})/([-a-z]*)\.html /newblog/$1/$2.shtml
Це захоплює назви файлів із тиреми. Однак, як -
це спеціальний символ у дужкових виразах, він повинен бути першим символом у виразі.
RewriteRule ^/blog/([0-9]{4})/([-0-9a-zA-Z]*)\.html /newblog/$1/$2.shtml
Ця версія захоплює будь-яке ім'я файлу з літерами, цифрами або -
символом у файлі-імені. Таким чином ви вказуєте кілька наборів символів у дужковому виразі.
Перепишіть прапори
Прапори за правилами перезапису мають безліч спеціальних значень та випадків використання .
RewriteRule ^/blog/([0-9]{4})/([-a-z]*).\html /newblog/$1/$2.shtml [L]
Прапор є [L]
в кінці вищезазначеного виразу. Можна використовувати кілька прапорів, розділених комою. Зв'язана документація описує кожну, але тут вони все одно:
L = Останній. Зупиніть обробку RewriteRules, коли цей збіг відповідає. Кількість замовлень!
C = ланцюг. Продовжуйте обробку наступної RewriteRule. Якщо це правило не відповідає, наступне правило не виконується. Детальніше про це пізніше.
E = Встановити змінну середовища. Apache має різні змінні середовища, які можуть впливати на поведінку веб-сервера.
F = заборонено Повертає помилку 403-забороненої, якщо це правило відповідає.
G = Пропало. Повертає помилку 410 Gone, якщо це правило відповідає.
Н = обробник. Примушує обробляти запит так, ніби він був заданим MIME-типом.
N = Далі. Примушує правило починати заново і знову відповідати. БУДЬ ОБЕРЕЖНИЙ! Цикли можуть призвести.
NC = Немає справи. Дозволяєjpg
щоб відповідати як jpg, так і JPG.
NE = Без втечі. Запобігає переписуванню спеціальних символів (.? # І т.д.) у їх еквіваленти шістнадцятковим кодом.
NS = Підзапити немає. Якщо ви використовуєте сервер-включено, це запобіжить збігу з включеними файлами.
P = проксі. Примушує правило керувати mod_proxy. Прозоро надайте контент з інших серверів, тому що ваш веб-сервер отримує його та повторно подає. Це небезпечний прапор, оскільки неякісно написаний перетворить ваш веб-сервер у відкритий проксі, і це погано.
PT = Пройти через. Враховуйте твердження псевдонімів у відповідності RewriteRule.
QSA = QSAдопов. Коли початковий рядок містить запит ( http://example.com/thing?asp=foo) додайте початковий рядок запиту до переписаного рядка. Зазвичай це було б відмовлено. Важливо для динамічного контенту.
R = перенаправлення. Надайте переспрямування HTTP на вказану URL-адресу. Можна також надати точний код переспрямування [R = 303]. Дуже схожий на те RedirectMatch
, що швидше і його слід використовувати, коли можливо.
S = Пропустити. Пропустити це правило.
T = Тип. Вкажіть тип mime для повернутого вмісту. Дуже схожа на AddType
директиву.
Ви знаєте, як я сказав, що RewriteCond
стосується одного і лише одного правила? Ну, можна обійти це ланцюжком.
RewriteEngine On
RewriteCond %{HTTP_REFERER} ^https?://serverfault\.com(/|$)
RewriteRule ^/blog/(.*)\.html /blog/$1.sf.html [C]
RewriteRule ^/blog/(.*)\.jpg /blog/$1.sf.jpg
Оскільки перший RewriteRule має прапор Chain, друге правило перезапису буде виконуватися, коли перше це робиться, тобто коли попереднє правило RewriteCond збігається. Зручно, якщо регулярні вирази Apache роблять ваш мозок боляче. Однак метод "все в одному рядку", на який я вказую в першому розділі, швидший з точки зору оптимізації.
RewriteRule ^/blog/([0-9]{4})/([-0-9a-zA-Z]*)\.html /newblog/$1/$2.shtml
Це можна спростити через прапори:
RewriteRule ^/blog/([0-9]{4})/([-0-9a-z]*)\.html /newblog/$1/$2.shtml [NC]
Також деякі прапори також застосовуються до RewriteCond. Помітно, NoCase.
RewriteCond %{HTTP_REFERER} ^https?://serverfault\.com(/|$) [NC]
Відповідатиме "ServerFault.com"