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

Перенос правил перезаписи в подкаталог с Apache на IIS

На старом хостинге Apache у нас были следующие .htaccess файл внутри public_html/adm:

<IfModule mod_rewrite.c>
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /adm/index.php [L]
</IfModule>

Это должно перенаправлять каждый URL после adm subdir к /adm/index.php файл, если путь не существует. И работает нормально.

Затем я перенес этот веб-сайт на IIS (v8.5) и с помощью инструмента «Импорт правил ...» попытался добиться того же эффекта, но сначала он возился с URL-адресами, отличными от тех, что находятся под /adm дорожка. Пытаясь решить эту проблему, я изменил исходный .htaccess файл немного, как показано ниже:

<IfModule mod_rewrite.c>
RewriteEngine On
RewriteCond adm/%{REQUEST_FILENAME} !-f
RewriteCond adm/%{REQUEST_FILENAME} !-d
RewriteRule adm/. /adm/index.php [L]
</IfModule>

В результате получаются следующие правила IIS:

<rewrite>
    <rules>
        <rule name="Imported Rule 1" enabled="true" stopProcessing="true">
            <match url="adm/." ignoreCase="false" />
            <conditions logicalGrouping="MatchAll">
                <add input="adm/{REQUEST_FILENAME}" matchType="IsFile" pattern="" ignoreCase="true" negate="true" />
                <add input="adm/{REQUEST_FILENAME}" matchType="IsDirectory" pattern="" ignoreCase="true" negate="true" />
            </conditions>
            <action type="Rewrite" url="/adm/index.php" />
        </rule>
    </rules>
</rewrite>

Сначала казалось, что это работает (1), но я быстро заметил, что действительные пути тоже перенаправляются (2). Как заставить его работать нормально?

  1. http://example.com/aaaa возвращает ошибку 404 и http://example.com/adm/aaaa возвращает содержимое http://example.com/adm/index.php (это ожидается).

  2. http://example.com/adm/images/logo.png, который является допустимым путем, возвращает содержимое файла index.php (это ошибочно).

Это результат правил перезаписи из web.config файл.

Спасибо.

Условия матча не выполняются. Это связано с (ошибочным) добавлением adm/ перед ними.

Ценность REQUEST_FILENAME переменная сервера - это полный путь в файловой системе к запрашиваемому файлу (или каталогу). В моем конкретном тестовом примере:

URL запроса: http://example.com/adm/images/logo.png
{REQUEST_FILENAME}: F:\IIS\example.com\adm\assets\img\logo.png

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

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

Обновленные правила для web.config файл следующим образом.

<rewrite>
    <rules>
        <rule name="Imported Rule 1" enabled="true" stopProcessing="true">
            <match url="(adm\/).*" ignoreCase="false" />
            <conditions logicalGrouping="MatchAll">
                <add input="{REQUEST_FILENAME}" matchType="IsFile" pattern="" ignoreCase="true" negate="true" />
                <add input="{REQUEST_FILENAME}" matchType="IsDirectory" pattern="" ignoreCase="true" negate="true" />
            </conditions>
            <action type="Rewrite" url="/adm/index.php" />
        </rule>
    </rules>
</rewrite>

Ваше регулярное выражение неверно. Не соответствует всему значению после /

Результат adm/. возвращает совпадение для adm/i. Таким образом, можно предположить, что файл не существует.

Ваше регулярное выражение должно быть: adm/.*

При создании правила в графическом интерфейсе IIS нажмите Test Pattern кнопка в Match URL раздел, чтобы увидеть результаты.