Перенаправлення, зміна URL-адрес або перенаправлення HTTP на HTTPS в Apache - все, що ви хотіли знати про правила Mod_Rewrite, але не боялися запитувати


264

Це канонічне запитання про mod_rewrite Apache.

Зміна URL-адреси запиту або перенаправлення користувачів на іншу URL-адресу, ніж ту, яку вони спочатку запитували, здійснюється за допомогою mod_rewrite. Сюди входять такі речі, як:

  • Зміна HTTP на HTTPS (або навпаки)
  • Зміна запиту на сторінку, яка вже не існує, на нову заміну.
  • Змінення формату URL-адреси (наприклад,? Id = 3433 в / id / 3433)
  • Представлення іншої сторінки на основі браузера, на основі реферала, на основі всього можливого під місяцем і сонцем.
  • Все, що ви хочете зіпсувати з URL-адресою

Все, що ви хотіли знати про правила Mod_Rewrite, але не боялися запитувати!

Як я можу стати експертом з написання правил mod_rewrite?

  • Який основний формат і структура правил mod_rewrite?
  • Яка форма / аромат регулярних виразів мені потрібна, щоб мати чітке розуміння?
  • Які найпоширеніші помилки / підводні камені при написанні правил перезапису?
  • Який хороший метод тестування та перевірки правил mod_rewrite?
  • Чи мають бути в курсі SEO або ефективність наслідків правил mod_rewrite?
  • Чи бувають загальні ситуації, коли mod_rewrite може здатися правильним інструментом для роботи, але це не так?
  • Назвіть кілька поширених прикладів?

Місце для перевірки своїх правил

Htaccess тестер веб - сайт є відмінним місцем , щоб грати з вашими правилами і протестувати їх. Він навіть показує вихід налагодження, щоб ви могли бачити, що збігається, а що ні.


9
Ідея цього питання полягає в тому, щоб дати близький шлях до всіх нескінченних запитань mod_rewrite, які звели з розуму наших більш регулярних користувачів. Це дуже схоже на те, що було зроблено з підмережами на сервері defaultfault.com/questions/49765/how-does-subnetting-work .
Кайл Брандт

1
Крім того, я не хочу дуже багато відгуків щодо цього питання , скоріше вони повинні перейти до відповіді. Я не хочу це робити, тому що я хочу переконатися, що плакат отримує повну заслугу за те, на що я сподіваюсь, це відповідь mod_rewrite, щоб закінчити всі питання mod_rewrite .
Кайл Брандт

4
Вибачте, я підтримав це питання. ;-) Я дійсно думаю, що він повинен з’являтися на (або поблизу) верхній частині mod-rewriteпошуку / фільтрів тегів.
Стівен Понеділок,

Хтось інший (tm) повинен обробляти загальні випадки використання. Я не знаю їх досить добре, щоб зробити це справедливим.
sysadmin1138

Можливо, це питання слід пов’язати з wi-тегом mod-rewrite, щоб зробити шлях ще коротшим.
beldaz

Відповіді:


224

Порядок синтаксису 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"


9
Молодці. [наповнювач]
EEAA

3
Дуже приємний mod_rewriteі регекс грунтовка. +1.
Стівен у понеділок,

3
Це іноді корисно знати , що RewriteCondнасправді обробляється післяRewriteRule підібраний. Ви можете сказати "докладніше про це пізніше" вгорі, де ви говорите "RewriteCond, що передує RewriteRule, робить це правило ONE умовним". Ви можете згадати, що регулярні вирази - це сумісні з Perl регулярні вирази. Також у вас є сторонній апостроф у "... RewriteRule вважає, що це строковий старт ..."
Денніс Вільямсон

2
RewriteRule ^/blog/.*/(.*)$ /newblog/$1не відповідає першому компоненту каталогу - переписувачі за замовчуванням жадібні. /.*/(.*) відповідає обом / 1 / (2) / і / 1/2/3/4/5 / (6) /, тому вам потрібно / [^ /] * /, щоб відповідати тільки ПЕРШИЙ шлях компонент.
адаптор

1
@ sysadmin1138, я вважаю, що ця відповідь хороша, але може бути кращою, якщо ви більше деталізуєте прапори E, N, NS, P, PT і S з прикладами, оскільки ці прапори не очевидно, як вони працюють і т.д.
Pacerier

39

Який основний формат і структура правил mod_rewrite?

Я відкладу на відмінну відповідь sysadmin1138 щодо цих питань.

Яка форма / аромат регулярних виразів мені потрібна, щоб мати чітке розуміння?

На додаток до порядку синтаксису, відповідності синтаксису / регулярних виразів та прапорів RewriteRule, окреслених sysadmin1138, я вважаю, що тут згадується, що mod_rewrite розкриває змінні середовища Apache на основі заголовків запитів HTTP та конфігурації Apache.

Я б порекомендував навчальний посібник з налагодження модуля AskApache для вичерпного списку змінних, які можуть бути доступні для mod_rewrite.

Які найпоширеніші помилки / підводні камені при написанні правил перезапису?

Більшість проблем із RewriteRule є наслідком нерозуміння синтаксису PCRE / невдачі належним чином уникнути спеціальних символів або відсутності розуміння вмісту змінної, що використовується для зіставлення.

Типові проблеми та рекомендоване усунення несправностей:

  • 500 - Внутрішня помилка сервера - Видаліть елементи управління каретки Windows у файлах конфігурації, якщо вони є, переконайтесь, що mod_rewrite увімкнено (оберніть директиви в IfModuleумовному режимі, щоб уникнути цього сценарію), перевірте синтаксис директив, коментуйте директиви, поки проблема не буде визначена
  • Цикл перенаправлення - Використовуйте RewriteLog та RewriteLogLevel, коментуйте директиви, поки проблема не буде визначена

Який хороший метод тестування та перевірки правил mod_rewrite?

Спочатку подивіться вміст змінної середовища, з якою ви плануєте співставити - якщо у вас встановлений PHP, це так само просто, як додавання наступного блоку до вашої програми:

<?php
  var_dump($_SERVER);
?>

... потім напишіть свої правила (бажано для тестування на сервері розробки) і відзначте будь-яке непослідовне збіг чи активність у вашому файлі Apache ErrorLog .

Для більш складних правил використовуйте RewriteLogдирективу mod_rewrite для входження активності у файл та набірRewriteLogLevel 3

Чи мають бути в курсі SEO або ефективність наслідків правил mod_rewrite?

AllowOverride allвпливає на продуктивність сервера, оскільки Apache повинен перевіряти наявність .htaccessфайлів та розбирати директиви з кожним запитом - якщо можливо, зберігайте всі директиви в конфігурації VirtualHost для вашого сайту або вмикайте .htaccessзміни замість лише для каталогів, які їм потрібні.

В Інструкціях Google для веб-майстрів чітко зазначено: "Не обманюйте своїх користувачів і не представляйте інший вміст у пошукових системах, ніж ви показуєте користувачам, що зазвичай називається" приховування "." - уникайте створення директив mod_rewrite, які фільтрують роботів пошукових систем.

Роботи пошукової системи віддають перевагу контенту 1: 1: відображення URI (це основа для ранжування посилань на вміст) - якщо ви використовуєте mod_rewrite для створення тимчасових переадресацій або ви подаєте один і той же вміст під декількома URI, подумайте про те, вказавши канонічний URI в ваші HTML документи.

Чи бувають загальні ситуації, коли mod_rewrite може здатися правильним інструментом для роботи, але це не так?

Це сама по собі величезна (і потенційно спірна) тема - краще (ІМХО) вирішувати питання використання в кожному конкретному випадку і нехай запитуючі вирішують, чи пропонуються запропоновані резолюції для їх потреб.

Назвіть кілька поширених прикладів?

Підказки mod_rewrite від AskApache охоплюють практично кожен загальний випадок використання, який регулярно з'являється, однак, "правильне" рішення для даного користувача може залежати від складності конфігурації користувача та існуючих директив (саме тому, як правило, це хороша ідея побачити, які ще директиви є у користувача, коли виникає запитання mod_rewrite).


Дякуємо за посилання AskApache. Це те, що я шукав!
sica07

Клоун AskApache офіційно не підтримується ASF. Багато з того, що він каже, є дискусійним чи явно неправильним.
адаптор

@adaptr Будь ласка, поділіться чудовими ресурсами, про які ви, мабуть, знаєте.
danlefree

"поширені ситуації, коли mod_rewrite може здатися правильним інструментом для роботи, але це не так?" - прості переадресації, де mod_rewrite вже не використовується. Використовуйте mod_alias Redirectабо RedirectMatchзамість цього. Дивіться також документи Apache: Коли не використовувати mod_rewrite
MrWhite

21

Як і багато адміністраторів / розробників, я роками боровся з тонкощами правил перезапису, і я незадоволений існуючою документацією на Apache, тому я вирішив як особистий проект дійти до основи того, як mod_rewriteнасправді працює і взаємодіє з рештою Apache core, тому протягом останніх кількох місяців я проводив інструментацію тестових випадків із strace+ свердлінням у вихідний код, щоб отримати обробку щодо всього цього.

Ось кілька ключових коментарів, які розробники правил перезапису повинні врахувати:

  • Деякі аспекти переписування є загальними для конфігурації сервера, віртуального хоста, каталог, .htaccess обробки проте
  • Деяка обробка дуже відрізняється для кореневого конфігурації (конфігурація сервера, віртуальний хост і каталог) на відміну від .htaccessобробки PerDir ( ).
  • Гірше, тому що обробка PerDir може майже беззаперечно запустити ВНУТРІШНЕ ПЕРЕМЕЧЕННЕ цикління, кореневі елементи конфігурації повинні бути записані, усвідомлюючи, що така обробка PerDir може спровокувати це.

Я хотів би сказати, що через це вам майже потрібно розділити переписані спільноти користувачів на дві категорії і трактувати їх як цілком окремі:

  • Ті, хто має кореневий доступ до конфігурації Apache . Зазвичай це адміністратор / розробник із сервером / VM, призначеним для програми, і повідомлення тут досить просте: уникайте використання .htaccessфайлів, якщо це можливо; робити все на своєму сервері або vhost config. Налагодження досить легко, оскільки розробник може встановити налагодження і має доступ до файлів rewrite.log.

  • Користувачі спільної розміщеної послуги (SHS) .

    • Такі користувачі повинні використовувати .htaccess/ Perdir обробку, оскільки альтернативи немає.
    • Гірше, що рівень вмінь таких користувачів (що стосується використання драбинкової логіки mod_rewrite, керованої регулярними виразками), як правило, значно менше, ніж досвідчених адміністраторів.
    • Apache та хостинг-провайдери не пропонують налагодження / діагностичної підтримки. Єдина діагностична інформація - це успішне перенаправлення, перенаправлення на неправильний URI. або код статусу 404/500 Це залишає їх розгубленими і безпорадними.
    • Apache надзвичайно слабко пояснює, як працює переписування для цього випадку використання. Наприклад, він не дає чіткого пояснення того, який .htaccessфайл PerDir обраний і чому. Це не пояснює тонкощі велосипедного руху PerDir і як цього уникнути.

Можливо, існує третя спільнота: адміністратор та обслуговуючий персонал у постачальників ТЗП, які опиняються ногами в обох таборах і повинні зазнавати наслідків вище.

Я написав кілька публікацій у блозі у стилі статті (наприклад, Докладніше про використання правил перезапису у файлах .htaccess ), який охоплює багато детальних пунктів, які я не повторюю тут, щоб ця публікація була короткою. У мене є власний спільний сервіс, а також підтримую деякі спеціалізовані проекти VM FLOSS. Я почав використовувати стандартний LAMP VM в якості тестового автомобіля для мого облікового запису SHS, але врешті-решт, я вважав, що краще зробити належний дзеркальний VM (описаний тут ).

Однак, з точки зору того, як спільнота адміністраторів повинна підтримувати .htaccessкористувачів, я вважаю, що нам потрібно розвиватись та пропонувати:

  • Узгоджений опис того, як система переписування насправді працює в PerDir-обробці
  • Набір вказівок / найкращих практик щодо написання .htaccessправил перезапису
  • Простий веб-аналізатор перезапису сценарію, подібний до html-аналізаторів W3C, але за допомогою якого користувачі можуть вводити тестові URI або тестові вектори того ж і отримати негайний журнал логічного потоку перезапису /
  • Підказки, як отримати вбудовану діагностику зі своїх правил (наприклад,

    • Використовуйте, [E=VAR:EXPR]використовуючи той факт, що EXPRрозширить зворотні параметри ($ N або% N), щоб зробити їх доступними в якості діагностики до цільового сценарію.
    • Якщо ви локально замовляєте свої правила перезапису, використовуючи прапорці [OR], [C], [SKIP] та [L], щоб вся схема перезапису працювала без необхідності використання внутрішнього перенаправлення, тоді ви можете додати наступне як правило 1, щоб уникнути всі клопоти циклічно:

      RewriteCond %{ENV:REDIRECT_STATUS} !=""
      RewriteRule .  -  [L]
      

Це добре задокументовано. Чому ви кажете, що документація цього не пояснює?
адаптер

2
Все, що вам потрібно зробити, це підписатися на .htaccessтеми, і ви побачите. Більшість початківців безнадійно плутаються - більшість із них мають перший досвід служби LAMP та mod_rewrite на спільній службі, а отже, не мають кореневого доступу до конфігурацій системи / vhost і їм доводиться використовувати за обробку .htaccessфайлів через файли. Є важливі відмінності, які новачок повинен "знекровити". Я вважав би себе енергетичним користувачем і все ще відкриваю тонкощі. Як я кажу, мені довелося використовувати сканування штрихів і вихідних кодів, щоб розробити деякі аспекти. :-(
TerryE

Я цілком погоджуюся. "Нам потрібно розділити переписані спільноти користувачів на дві категорії і розглядати їх як цілком окремі." Деякі користувачі використовують спільний хостинг і їм потрібно покладатися на це .htaccess, що жахливо тендітно, складно та заплутано навіть для експертів. У мене НЕ БУДЬ проблем.
Райан

15

Використання переписування

Є багато речей, які можна зробити з переписуванням. Перезаписи оголошуються за допомогою директиви Rewritemap, після чого вони можуть бути використані як в оцінках RewritCond, так і в підписках RewriteRule.

Загальний синтаксис для RewriteMap:

RewriteMap MapName MapType:MapSource

Наприклад:

RewriteMap examplemap txt:/path/to/file/map.txt

Потім ви можете використовувати назву карти для таких конструкцій:

${examplemap:key}

Карта містить пари ключ / значення. Якщо ключ знайдений, значення змінюється. Прості карти - це просто звичайні текстові файли, але ви можете використовувати хеш-карти і навіть SQL-запити. Більш детальна інформація знаходиться в документах:

http://httpd.apache.org/docs/2.2/mod/mod_rewrite.html#rewritemap

Немальовані рядки.

Існує чотири внутрішні карти, за допомогою яких можна зробити деякі маніпуляції. Особливо непомітні рядки можуть стати в нагоді.

Наприклад: Я хочу перевірити на рядок "café" в рядку запиту. Однак браузер уникне цього, перш ніж надсилати його на мій сервер, тому мені потрібно буде розібратися, яка версія, що уникнула URL-адреса, для кожної рядки, яку я хочу відповідати, або я можу просто скасувати її ...

RewriteMap unescape int:unescape

RewriteCond %{QUERY_STRING}  (location|place)=(.*)
RewriteCond ${unescape:%2}   café
RewriteRule ^/find/$         /find/1234? [L,R]

Зверніть увагу, як я використовую один RewriteCond, щоб просто зафіксувати параметр рядка запиту рядка запиту, а потім використати карту у другому rewriteCond, щоб не відтворити його. Потім це порівнюється. Також зауважте, як мені потрібно% 2 як ключ в переписуванні, оскільки% 1 буде містити або "location", або "place". Якщо ви використовуєте дужки для групування шаблонів, вони також будуть захоплені, якщо ви плануєте використовувати результат захоплення чи ні ...


Останнє речення не зовсім вірно. Двигун mod_rewriteregexp підтримує групи, що не захоплюють, такі як, (?:location|place)і в цьому прикладі буде лише одне захоплення.
TerryE

12

Які найпоширеніші помилки / підводні камені при написанні правил перезапису?

По-справжньому легкий підводний камінь - це коли ви переписуєте URL-адреси, які змінюють видимий шлях, наприклад, від /base/1234/index.htmlдо /base/script.php?id=1234. Будь-які зображення або CSS з відносними шляхами до місця розташування сценарію клієнт не знайде. Ряд варіантів вирішення цього питання можна знайти на цьому файлі .


1
Дякуємо за посилання Зокрема, працюючи з іншими членами команди, які не знайомі з переписуванням, я вважаю, що додавання <base>тегу є найпростішим для просування та все ще дозволяє відносні шляхи.
kontur
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.