Перезапись URL в IIS7: как не удалить протокол HTTPS из переписанного URL? - PullRequest
22 голосов
/ 09 апреля 2010

Я работаю над веб-сайтом, который использует функцию перезаписи URL в IIS 7 для постоянного перенаправления с example.com на www.example.com, а также переписывает с похожих доменных имен на «основное», например от www.examples.com до www.example.com.

Это правило перезаписи, показанное ниже, работает хорошо уже некоторое время. Однако недавно мы добавили поддержку HTTPS и заметили, что если пользователи посещают один из URL-адресов, которые должны быть перезаписаны на www.example.com, HTTPS отбрасывается. Например, если пользователь посещает https://example.com, он перенаправляется на http://www.example.com,, тогда как мы хотели бы, чтобы его отправили на https://www.example.com.

Вот интересующее правило переписывания (в Web.config):

<rule name="Canonical Host Name" stopProcessing="true">
    <match url="(.*)" />

    <conditions logicalGrouping="MatchAny">
        <add input="{HTTP_HOST}" pattern="^example\.com$" />
        <add input="{HTTP_HOST}" pattern="^(www\.)?example\.net$" />
        <add input="{HTTP_HOST}" pattern="^(www\.)?example\.info$" />
        <add input="{HTTP_HOST}" pattern="^(www\.)?examples\.com$" />
    </conditions>

    <action type="Redirect" url="http://www.example.com/{R:1}" redirectType="Permanent" />
</rule>

Как видите, атрибут url элемента действия указывает непосредственно на http://,, поэтому я понимаю, почему https://example.com перенаправляется на http://www.example.com. Мой вопрос: как это исправить? Я попытался (наивно) просто удалить часть http: // из атрибута url, но это не сработало.

Ответы [ 4 ]

40 голосов
/ 19 апреля 2012

Вот ответ Скотта с улучшениями Хасана. Это должно охватывать смешанные сайты SSL / не-SSL. Правило в основном гласит: «если в URL нет www.example.com», перенаправьте его на него. По сути ... вы перенаправляете людей, которые посещают вас, без www или напрямую на ваш IP-адрес.

<rewrite>
<rules>
    <rule name="Canonical Host Name" stopProcessing="true">
        <match url="(.*)" />
        <conditions logicalGrouping="MatchAll">
            <add input="{HTTP_HOST}" pattern="^www\.example\.com$" negate="true" />
        </conditions>
        <action type="Redirect" url="{MapSSL:{HTTPS}}www.example.com/{R:1}" redirectType="Permanent" />
    </rule>
</rules>
<rewriteMaps>
    <rewriteMap name="MapSSL" defaultValue="http://">
        <add key="ON" value="https://" />
        <add key="OFF" value="http://" />
    </rewriteMap>
</rewriteMaps>
</rewrite>
10 голосов
/ 10 апреля 2010

Разобрался с ответом с некоторой помощью от моих коллег.

Мне нужно было использовать несколько правил с условием {HTTPS}. Обратите внимание на условие {HTTPS} в приведенных ниже правилах.

<rule name="Canonical Host Name (HTTP)" stopProcessing="true">
    <match url="(.*)" />

    <conditions logicalGrouping="MatchAny">
        <add input="{HTTPS}" pattern="OFF" />
        <add input="{HTTP_HOST}" pattern="^example\.com$" />
    </conditions>

    <action type="Redirect" url="http://www.example.com/{R:1}" redirectType="Permanent" />
</rule>

<rule name="Canonical Host Name (HTTPS)" stopProcessing="true">
    <match url="(.*)" />

    <conditions logicalGrouping="MatchAny">
        <add input="{HTTPS}" pattern="ON" />
        <add input="{HTTP_HOST}" pattern="^example\.com$" />
    </conditions>

    <action type="Redirect" url="https://www.example.com/{R:1}" redirectType="Permanent" />
</rule>

Затем я повторил приведенную выше пару правил для альтернативных доменных имен.

7 голосов
/ 11 марта 2012

Если вы просто хотите перенаправить на основе используемого в настоящее время протокола (в соответствии с вашим последним примером), то есть гораздо более простое решение, которое позволит вдвое сократить количество необходимых вам правил. Вот что я узнал от моего коллеги.

Как вы видели, аргумент {HTTPS} будет содержать значение ON или OFF. Вы можете сопоставить это значение с https: // или http: //, введя это значение в карту перезаписи.

Вот как это будет работать:

1 - Создать раздел карты перезаписи для сопоставления значения {HTTPS}:

    <rewriteMap name="MapProtocol" defaultValue="OFF">
      <add key="ON" value="https://" />
      <add key="OFF" value="http://" />
    </rewriteMap>

Вам решать, хотите ли вы включить только протокол или точку с запятой и косую черту. Для решения это не имеет значения, но имейте в виду, куда бы вы ни ссылались.

2- Обращайтесь к этой карте везде, где вам нужно. В этом примере он используется в исходящих правилах, но он также будет работать в вашем сценарии:

    <rule name="Outbound-Rule Name" stopProcessing="true" preCondition="ResponseIsHtml">
      <match filterByTags="A, Link, Script" pattern="YOUR PATTERN" />
      <action type="Rewrite" value="{MapProtocol:{HTTPS}}{HTTP_HOST}/REST OF RELATIVE LINK HERE" />
    </rule>

Вот и все, модуль перезаписи URL теперь должен автоматически использовать правильный протокол для ваших ссылок в зависимости от того, используете ли вы https или, конечно, http.

Надеюсь, это поможет!

1 голос
/ 20 сентября 2013

Вот междоменное решение, которое работает не только на example.com, но и на любом домене

<rewrite>
    <rules>
        <rule name="Canonical Host Name" stopProcessing="true">
            <match url="(.*)" />
            <conditions logicalGrouping="MatchAll">
                <add input="{HTTP_HOST}" pattern="^www\.([.a-zA-Z0-9]+)$" negate="true" />
            </conditions>
            <action type="Redirect" url="{MapProtocol:{HTTPS}}www.{HTTP_HOST}/{R:0}" redirectType="Permanent" />
        </rule>
    </rules>
    <rewriteMaps>
        <rewriteMap name="MapProtocol" defaultValue="OFF">
            <add key="ON" value="https://" />
            <add key="OFF" value="http://" />
        </rewriteMap>
    </rewriteMaps>
</rewrite>
...