Назад | Перейти на главную страницу

Настройка htaccess / mod_rewrite для обслуживания статических файлов со знаком вопроса в URL

Я только что взял на хостинг древний сайт, который был преобразован из asp в статический html, состоящий примерно из 6000 файлов. Однако моему серверу не нравятся имена файлов, что дает ошибку 404. Все URL-адреса имеют вид:

filename.asp?id=123&a=something.html

где id всегда целое число и a всегда представляет собой строку символов и цифр.

Есть ли способ использовать htaccess и mod_rewrite, чтобы сообщить ему, что вопросительный знак является частью URL-адреса, а не обозначает строку запроса?

Вы, наверное, уже знаете, что вы не первый человек к есть эта потребность :)

# Allow filenames containing '?' to be served by escaping the '?' in the HTTP
# request so it's not interpreted as a query string.
#
# Apache 2.2: set query string to empty by ending rewritten path with '?'.
# Apache 2.4: use the qsdiscard flag instead
#
RewriteCond %{QUERY_STRING} !=""
RewriteRule ^/(.*) /$1\%3F%{QUERY_STRING}? [noescape,last,redirect]

Ключ - комбинация добавления перенаправления и NE / noescape чтобы гарантировать, что apache не ускользнет от того, чего мы не хотим.

Вышеупомянутое правило будет означать, что весь сайт при этой перезаписи будет обрабатывать ? как часть имени файла. Если вам нужно, чтобы он соответствовал вашему filename.asp - просто добавьте его в RewriteRule

Я бы посоветовал переписать, чтобы напрямую обслуживать файл, избегая "?" в "\% F3".

Для обслуживания файлов:

RewriteCond %{QUERY_STRING} !=""
RewriteRule ^(.*)$ $1\%3F%{QUERY_STRING}? [L]

Сделайте то же самое для папок (например, обслуживайте index.html - адаптируйте index.html под свои нужды)

RewriteCond %{REQUEST_FILENAME} ^.*/$
RewriteCond %{QUERY_STRING} !=""
RewriteRule ^(.*)/$ $1/index.html\%3F%{QUERY_STRING}? [L]

Во-первых, мы проверяем, существует ли файл (см. Следующий абзац об этом), во-вторых, мы проверяем, есть ли у нас строка запроса (в противном случае, обслуживаем файл как обычно), затем добавляем "?" и исходную строку запроса и обслужить ее.

Я добавляю "?" в конце, чтобы стереть QueryString (поскольку он уже обработан) и избежать повторного применения правила (например, при обслуживании файла в подкаталоге). Другое решение - использовать флаг «КОНЕЦ» (см. http://httpd.apache.org/docs/current/en/mod/mod_rewrite.html#rewriterule). Согласно той же странице и как указано в @csharkey и @Gavin C, [qsdiscard] может быть добавлен вместо этого в apache 2.4:

RewriteRule ^(.*)/$ $1/index.html\%3F%{QUERY_STRING}? [L,qsdiscard]

Предостережение: я не тестировал это решение тщательно, поэтому ошибки могут остаться.

Я преобразовал древний сайт Joomla с wget --mirror. В моем случае все ссылки прошли через файл index.php, поэтому все они похожи на site.com/index.php?blabla=haha.

Я решил проблему, добавив файл index.php со следующим содержанием:

<?php

include 'index.php?' . $_SERVER['QUERY_STRING'];

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