Двунаправленная перезапись / перенаправление URL в IIS7.5

#asp.net #iis-7 #url-rewriting #iis-7.5

#asp.net #iis-7 #перезапись URL #iis-7.5

Вопрос:

Прежде всего, я хотел бы извиниться за нелепое название. Я не пытаюсь казаться крутым или умным, используя слово «двунаправленный», я просто искренне не мог придумать другого способа описать это. Обещаю.

Перейдем к моей проблеме. У меня есть следующее в разделе <system.webserver> / <rewrite> / <rules> моего Web.config.

 <!-- Who We Are -->
<rule name="1A">
    <match url="^whoweare.aspx$" />
    <action type="Redirect" url="who-we-are" redirectType="Permanent" />
</rule>
<rule name="1B">
    <match url="^who-we-are$" />
    <action type="Rewrite" url="whoweare.aspx" />
</rule>

<!-- What We Do -->
<rule name="2A">
    <match url="^whatwedo.aspx$" />
    <action type="Redirect" url="what-we-do" redirectType="Permanent" />
</rule>
<rule name="2B">
    <match url="^what-we-do$" />
    <action type="Rewrite" url="whatwedo.aspx" />
</rule>
  

Теперь это работает потрясающе. Фактически, если вы посещаете URL http://example.com/whoweare.aspx (который является фактическим URL страницы), вы будете перенаправлены на 301 URL http://example.com/who-we-are (виртуальный URL), и если вы перейдете по виртуальному URL, вы будете перезаписаны на фактический URL.

Это означает суперсексуальные URL-адреса без дублирования, и это также не приводит к взаимной перезаписи, так что всем улыбается.

Мой вопрос заключается в следующем: можно ли это сделать более элегантно?

Немного обременительно выписывать два правила, чтобы гарантировать, что одно перенаправляется на другое, а другое переписывается на первое. Возможно ли написать одно правило, которое обеспечит функциональность двух вышеупомянутых?

Ответ №1:

Элегантность — это субъективный термин, я предполагаю, что есть пара способов, которые были бы лучше, например, использовать расширяемость перезаписи и реализовать причудливую логику отображения, но на сегодняшний день я бы рекомендовал использовать всего 2 правила, одно для перенаправления и одно для перезаписи, и при этом просто использовать карты перезаписи, что сделает управление ими немного более читабельным (но все еще болезненным), например, приведенный ниже, теперь вам нужно будет только поддерживать карты и больше никогда не иметь дела с правилами:

 <system.webServer>
    <rewrite>
        <rules>
            <rule name="Rewrite From Pretty URL" stopProcessing="true">
                <match url=".*" />
                <conditions>
                    <add input="{URLsToRewrite:{REQUEST_URI}}" pattern="(. )" />
                </conditions>
                <action type="Rewrite" url="{C:1}" appendQueryString="false" />
            </rule>
            <rule name="Redirect To Pretty URL" stopProcessing="true">
                <match url=".*" />
                <conditions>
                    <add input="{URLsToRedirect:{REQUEST_URI}}" pattern="(. )" />
                </conditions>
                <action type="Redirect" url="{C:1}" appendQueryString="false" />
            </rule>
        </rules>
        <rewriteMaps>
            <rewriteMap name="URLsToRewrite">
                <add key="/who-we-are" value="/whoweare.aspx" />
                <add key="/what-we-do" value="/whatwedo.aspx" />
            </rewriteMap>
            <rewriteMap name="URLsToRedirect">
                <add key="/whoweare.aspx" value="/who-we-are" />
                <add key="/whatwedo.aspx" value="/what-we-do" />
            </rewriteMap>
        </rewriteMaps>
    </rewrite>
</system.webServer>
  

Комментарии:

1. Оооо, здорово. Мне стыдно признаться, что я не знал о картах перезаписи. Это, безусловно, кажется более удобным подходом. Однако вы не возражаете, если я задам пару вопросов о том, что происходит в представленном вами коде? Во-первых, я не совсем уверен, что <match url=".*" /> на самом деле соответствует, и как это может просто соответствовать всему? Во-вторых, {REQUEST_URI} вызовет ли проблемы при локальной работе, поскольку я могу работать в более глубокой структуре каталогов, чем в релизной версии? Наконец, в чем разница между {R:n} и {C:n} ? Огромное спасибо Карлосу.

2. . * указывает ему, чтобы он соответствовал всему в URL-адресе (не включая строку запроса) для анализа каждого запроса. REQUEST_URI будет соответствовать всему URL-адресу (включая строку запроса) с точностью до корня сайта «/». Простой способ взглянуть на это — включить трассировку: learn.iis.net/page.aspx/467/… Наконец, {R:#} вернет совпадения в пределах соответствия URL-адреса (в приведенном выше случае.*), а {C:#} вернет совпадения в пределах условий (в данном случае результат применения карты. Для перезаписи URL есть форум по адресу forums.iis.net/1152.aspx

3. есть ли способ использовать ту же карту перезаписи для достижения двунаправленной перезаписи?