Как переписать URL-адреса с помощью mod_rewrite для Apache в Ubuntu 16.04
Введение
В этом руководстве мы активируем и узнаем, как управлять перезаписью URL-адресов с помощью модуля Apache 2 mod_rewrite
. Этот модуль позволяет нам более аккуратно переписывать URL-адреса, переводя удобочитаемые пути в строки запроса, удобные для кода, или перенаправляя URL-адреса на основе дополнительных условий.
Это руководство разделено на две части. Первый устанавливает пример веб-сайта и охватывает простой пример перезаписи. Вторая часть содержит еще два подробных примера часто используемых правил перезаписи.
Предпосылки
Чтобы следовать этому руководству, вам понадобятся:
- Один сервер Ubuntu 16.04, настроенный с помощью этого руководства по начальной настройке сервера, включая пользователя без полномочий root и брандмауэр.
- Apache 2 установлен на вашем сервере, выполнив шаг 1 инструкции по установке стека Linux, Apache, MySQL, PHP (LAMP) в Ubuntu 16.04.
Шаг 1 — Включение mod_rewrite
Во-первых, нам нужно активировать mod_rewrite
. Он доступен, но не включен при чистой установке Apache 2.
- sudo a2enmod rewrite
Это активирует модуль или предупредит вас о том, что модуль уже включен. Чтобы эти изменения вступили в силу, перезапустите Apache.
- sudo systemctl restart apache2
mod_rewrite
теперь полностью включен. На следующем шаге мы создадим файл .htaccess
, который будем использовать для определения правил перезаписи для перенаправлений.
Шаг 2 — Настройка .htaccess
Файл .htaccess
позволяет нам изменять наши правила перезаписи без доступа к файлам конфигурации сервера. По этой причине .htaccess
имеет решающее значение для безопасности вашего веб-приложения. Точка перед именем файла гарантирует, что файл скрыт.
Примечание. Любые правила, которые вы можете поместить в файл .htaccess
, также можно поместить непосредственно в файлы конфигурации сервера. Фактически, официальная документация Apache рекомендует использовать файлы конфигурации сервера вместо .htaccess
, потому что Apache обрабатывает их быстрее.
Однако в этом простом примере прирост производительности будет незначительным. Кроме того, установка правил в .htaccess
удобна, особенно при наличии нескольких веб-сайтов на одном сервере. Чтобы изменения вступили в силу, не требуется перезагрузка сервера, а для редактирования этих правил не требуются привилегии root, что упрощает обслуживание и делает возможным внесение изменений с непривилегированной учетной записью. Некоторое популярное программное обеспечение с открытым исходным кодом, такое как Wordpress и Joomla, часто использует файл .htaccess
, чтобы программное обеспечение могло изменять и создавать дополнительные правила по запросу.
Прежде чем мы сможем начать, нам нужно будет настроить и защитить еще несколько настроек.
По умолчанию Apache запрещает использование файла .htaccess
для применения правил перезаписи, поэтому сначала вам нужно разрешить изменения в файле. Откройте файл конфигурации Apache по умолчанию с помощью nano
или вашего любимого текстового редактора.
- sudo nano /etc/apache2/sites-available/000-default.conf
Внутри этого файла вы найдете блок
, начинающийся с первой строки. Внутри этого блока добавьте следующий новый блок, чтобы ваш файл конфигурации выглядел следующим образом. Убедитесь, что все блоки имеют правильный отступ.
<VirtualHost *:80>
<Directory /var/www/html>
Options Indexes FollowSymLinks MultiViews
AllowOverride All
Require all granted
</Directory>
. . .
</VirtualHost>
Сохраните и закройте файл. Чтобы эти изменения вступили в силу, перезапустите Apache.
- sudo systemctl restart apache2
Теперь создайте файл .htaccess
в корневом каталоге веб-сайта.
- sudo nano /var/www/html/.htaccess
Добавьте эту строку вверху нового файла, чтобы активировать механизм перезаписи.
RewriteEngine on
Сохраните файл и выйдите.
Теперь у вас есть рабочий файл .htaccess
, который вы можете использовать для управления правилами маршрутизации вашего веб-приложения. На следующем шаге мы создадим образцы файлов веб-сайта, которые будем использовать для демонстрации правил перезаписи.
Шаг 3 — Настройка перезаписи URL
Здесь мы настроим базовую перезапись URL-адресов, которая преобразует красивые URL-адреса в фактические пути к коду. В частности, мы разрешим пользователям доступ к http://your_server_ip/about
.
Начните с создания файла с именем about.html
в корневом каталоге веб-сайта.
- sudo nano /var/www/html/about.html
Скопируйте следующий код HTML в файл, затем сохраните и закройте его.
<html>
<head>
<title>About Us</title>
</head>
<body>
<h1>About Us</h1>
</body>
</html>
Вы можете получить доступ к этой странице по адресу http://your_server_ip/about.html
, но обратите внимание, что если вы попытаетесь получить доступ к http://your_server_ip< /mark>/about
вы увидите ошибку 404 Not Found. Если вы хотите, чтобы пользователи получали доступ к странице, используя вместо этого просто about
, правила перезаписи разрешат эту самую функциональность.
Все RewriteRules
соответствуют следующему формату:
RewriteRule pattern substitution [flags]
RewriteRule
определяет директиву.шаблон
– это регулярное выражение, которое соответствует нужной строке из URL-адреса, который зритель вводит в браузере.подстановка
— это путь к фактическому URL-адресу, т. е. путь файловых серверов Apache.флаги
— это необязательные параметры, которые могут изменить работу правила.
Откройте файл .htaccess
.
- sudo nano /var/www/html/.htaccess
После первой строки добавьте RewriteRule
, отмеченный красным, и сохраните файл.
RewriteEngine on
RewriteRule ^about$ about.html [NC]
В этом случае ^about$
— это шаблон, about.html
— замена, а [NC]
— флаг. В нашем примере используется несколько символов со специальным значением:
^
указывает начало URL послеyour_server_ip/
.$
указывает на конец URL-адреса.about
соответствует строке \about.about.html
– это фактический файл, к которому обращается пользователь.[NC]
– это флаг, делающий правило нечувствительным к регистру.
Теперь у вас должен быть доступ к http://your_server_ip/about
в вашем браузере. Фактически, с приведенным выше правилом следующие URL-адреса будут указывать на about.html
:
http://your_server_ip/about
из-за определения правила.http://your_server_ip/About
, так как правило нечувствительно к регистру.http://ваш_сервер_ip/about.html
, потому что исходное правильное имя файла всегда будет работать.
Следующее не будет:
http://ваш_сервер_ip/about/
, поскольку в правиле явно указано, что послеabout
с использованиемне может быть ничего $
символ.http://your_server_ip/contact
, поскольку он не соответствует строкеabout
в правиле.
Теперь у вас есть работающий файл .htaccess
с простым правилом, которое вы можете изменить и расширить в соответствии со своими потребностями. В следующих разделах мы покажем два дополнительных примера часто используемых директив.
Пример 1. Упрощение строк запроса с помощью RewriteRule
Веб-приложения часто используют строки запроса, которые добавляются к URL-адресу с помощью вопросительного знака (?
) после адреса. Отдельные параметры разделяются амперсандом (&
). Строки запроса могут использоваться для передачи дополнительных данных между отдельными страницами приложения.
Например, страница результатов поиска, написанная на PHP, может использовать такой URL-адрес, как http://example.com/results.php?item=shirt&season=summer
. В этом примере воображаемому скрипту приложения result.php
передаются два дополнительных параметра: item
со значением shirt
и сезон
со значением лето
. Приложение может использовать информацию строки запроса, чтобы создать правильную страницу для посетителя.
Правила перезаписи Apache часто используются для упрощения таких длинных и неприятных ссылок, как показано выше, в дружественные URL-адреса, которые легче набирать и интерпретировать визуально. В этом примере мы хотели бы упростить приведенную выше ссылку, чтобы она стала http://example.com/shirt/summer
. Значения параметров shirt
и summer
по-прежнему находятся в адресе, но без строки запроса и имени скрипта.
Вот одно правило для реализации этого:
RewriteRule ^shirt/summer$ results.php?item=shirt&season=summer [QSA]
shirt/summer
явно сопоставляется с запрошенным адресом, и вместо этого Apache получает указание обслуживать results.php?item=shirt&season=summer
.
Флаги [QSA]
обычно используются в правилах перезаписи. Они говорят Apache добавить любую дополнительную строку запроса к обслуживаемому URL-адресу, поэтому, если посетитель введет http://example.com/shirt/summer?page=2
, сервер ответит results.php?item=shirt&season=summer&page=2
. Без него дополнительная строка запроса будет отброшена.
Хотя этот метод обеспечивает желаемый эффект, название предмета и время года жестко закодированы в правиле. Это означает, что правило не будет работать для любых других предметов, таких как брюки
, или сезонов, таких как зима
.
Чтобы сделать правило более общим, мы можем использовать регулярные выражения для сопоставления частей исходного адреса и использовать эти части в шаблоне замены. Модифицированное правило будет выглядеть следующим образом:
RewriteRule ^([A-Za-z0-9]+)/(summer|winter|fall|spring) results.php?item=$1&season=$2 [QSA]
Первая группа регулярных выражений в круглых скобках соответствует строке, содержащей буквенно-цифровые символы и числа, такие как shirt
или pants
, и сохраняет соответствующий фрагмент как переменную $1
. Вторая группа регулярных выражений в скобках точно соответствует лето
, зима
, осень
или весна
и аналогичным образом сохраняет соответствующий фрагмент как $2
.
Совпадающие фрагменты затем используются в результирующем URL-адресе в переменных item
и season
вместо жестко заданных значений shirt
и summer
. мы использовали раньше.
Вышеприведенное преобразует, например, http://example.com/pants/summer
в http://example.com/results.php?item=pants&season=summer
. Этот пример также рассчитан на будущее, позволяя правильно переписать несколько элементов и времен года с использованием одного правила.
Пример 2. Добавление условий с помощью логики с использованием RewriteConds
Правила перезаписи не обязательно всегда оцениваются одно за другим без каких-либо ограничений. Директива RewriteCond
позволяет нам добавлять условия к нашим правилам перезаписи, чтобы контролировать, когда правила будут обрабатываться. Все RewriteConds
имеют следующий формат:
RewriteCond TestString Condition [Flags]
RewriteCond
указывает директивуRewriteCond
.TestString
– это строка для проверки.Условие
– это шаблон или условие для соответствия.Флаги
– это необязательные параметры, которые могут изменять условия и правила оценки.
Если RewriteCond
оценивается как true, будет рассмотрен следующий за ним RewriteRule
. Если это не так, правило будет отменено. Несколько RewriteCond
могут быть использованы один за другим, и с поведением по умолчанию все они должны оцениваться как true, чтобы следующее правило учитывалось.
В качестве примера предположим, что вы хотите перенаправить все запросы к несуществующим файлам или каталогам на вашем сайте обратно на домашнюю страницу вместо отображения стандартной страницы ошибки 404 Not Found. Это может быть достигнуто с помощью следующих правил условий:
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /
С вышеизложенным:
%{REQUEST_FILENAME}
— строка для проверки. В данном случае это запрошенное имя файла, которое является системной переменной, доступной для каждого запроса.-f
— это встроенное условие, которое проверяет, существует ли запрошенное имя на диске и является ли оно файлом.!
— это оператор отрицания. В совокупности!-f
оценивается как true, только если указанное имя не существует или не является файлом.- Аналогично,
!-d
оценивается как true, только если указанное имя не существует или не является каталогом.
RewriteRule
в последней строке вступит в силу только для запросов к несуществующим файлам или каталогам. Сам RewriteRule
очень прост и перенаправляет каждый запрос в корень веб-сайта /
.
mod_rewrite
— это полезный модуль Apache, который можно эффективно использовать для обеспечения удобочитаемости URL-адресов. Из этого руководства вы узнали, как использовать директиву RewriteRule
для перенаправления URL-адресов, включая URL-адреса со строками запроса. Вы также узнали, как условно перенаправлять URL-адреса с помощью директивы RewriteCond
.
Если вы хотите узнать больше о mod_rewrite
, взгляните на официальную документацию Apache для mod_rewrite.