0

在尝试帮助 iis.net 论坛上的一位开发人员后,我开始寻找一种更好的方式来进行重定向。因此,我结束了这篇文章。

我接受了很多这些想法并开始实现我自己的版本。一切似乎都很好,但我在路上遇到了一个颠簸,我希望你能提供帮助。

好的,快速解释一下我的规则:

我的想法是测试 url,如果我发现它有问题,我会重写 url 并让它继续,而不是立即重定向它。如果在任何时候我重写了 url,我将自定义服务器变量“重定向”设置为 true。然后最后,我测试我的自定义服务器变量是否为真并重定向用户。

它的重点是只有一个 301 重定向,而不是一系列重定向。

这些是我的规则(对不起墙):

<rules>
  <rule name="WhiteList - resources" stopProcessing="true">
    <match url="^resources/" />
    <conditions logicalGrouping="MatchAll" trackAllCaptures="false" />
    <action type="None" />
  </rule>

  <rule name="Redirect subdomains with www to non-www" stopProcessing="false">
    <match url="(.*)" />
    <conditions logicalGrouping="MatchAll" trackAllCaptures="false">
      <add input="{HTTP_HOST}" pattern=".*localhost.*" negate="true" />
      <add input="{HTTP_HOST}" pattern="^www\.(.*)\.([^\.]+)\.([^\.]+)$" />
    </conditions>
    <action type="Rewrite" url="http://{C:1}.{C:2}.{C:3}{HTTP_URL}" />
    <serverVariables>
      <set name="Redirect" value="true" />
    </serverVariables>
  </rule>
  <rule name="Redirect top domains with non-www to www" stopProcessing="false">
    <match url="(.*)" />
    <conditions logicalGrouping="MatchAll" trackAllCaptures="false">
      <add input="{HTTP_HOST}" pattern=".*localhost.*" negate="true" />
      <add input="{HTTP_HOST}" pattern="^([^\.]+)\.([^\.]+)$" />
    </conditions>
    <action type="Rewrite" url="http://www.{HTTP_HOST}{HTTP_URL}" />
    <serverVariables>
      <set name="Redirect" value="true" />
    </serverVariables>
  </rule>

  <rule name="SEO - Remove trailing slash" stopProcessing="false">
    <match url="(.*)/$" />
    <conditions>
      <add input="{REQUEST_FILENAME}" matchType="IsFile" negate="true" />
      <add input="{REQUEST_FILENAME}" matchType="IsDirectory" negate="true" />
    </conditions>
    <action type="Rewrite" url="{R:1}" />
    <serverVariables>
      <set name="Redirect" value="true" />
    </serverVariables>
  </rule>
  <rule name="SEO - ToLower" stopProcessing="false">
    <match url="(.*)" ignoreCase="false" />
    <conditions logicalGrouping="MatchAll" trackAllCaptures="false">
      <add input="{URL}" pattern="[A-Z]" ignoreCase="false" />
      <add input="{URL}" pattern="^.*?\.(axd|css|js|jpg|jpeg|png|gif|ashx|asmx|svc).*?$" negate="true" />
      <add input="{URL}" pattern="^.*/(webshop)/.*$" negate="true" />
    </conditions>
    <action type="Rewrite" url="{ToLower:{R:1}}" />
    <serverVariables>
      <set name="Redirect" value="true" />
    </serverVariables>
  </rule>
  <rule name="SEO - remove default.aspx" stopProcessing="false">
    <match url="(.*?)/?default\.aspx$" />
    <action type="Rewrite" url="{R:1}" />
    <serverVariables>
      <set name="Redirect" value="true" />
    </serverVariables>
  </rule>
  <rule name="SEO - Trim aspx" stopProcessing="false">
    <match url="(.*)\.aspx$" />
    <action type="Rewrite" url="{R:1}" />
    <serverVariables>
      <set name="Redirect" value="true" />
    </serverVariables>
  </rule>

  <rule name="SEO - non-canonical redirect" stopProcessing="true">
    <match url="^(.*)" />
    <conditions>
      <add input="{Redirect}" pattern="true" />
    </conditions>
    <action type="Redirect" url="{R:1}" />
    <serverVariables>
      <set name="Redirect" value="false" />
    </serverVariables>
  </rule>
</rules>

现在它的大部分实际上工作得很好,但我似乎对裸域有一些问题。

如果我使用带有 www 的子域(应该重定向到非 www),那么它似乎失败了。有趣的是,如果我转到子页面,它可以正常工作。

(我不能发布更多的网址,因为我是新来的:(我想感谢其他人让我开始做这件事。)

我已经将它追溯到服务器变量{HTTP_URL},因为如果我删除它,它不会失败。然而,它当然也没有做它应该做的事情(它总是重定向到裸域)。我尝试了各种变量:{URL}{REQUEST_URI}它们似乎都以相同的错误结束,这有点烦人。

如果有人对规则有一些改进,请随时回复,我喜欢与他们合作,我想做出近乎完美的重定向,所以欢迎任何建议。

4

2 回答 2

1

这最终更像是版本 1,我已经对其进行了改进以避免服务器变量。现在我使用一系列重写规则将 url 转换为我喜欢的内容,并附加下划线。然后剥离下划线,然后重定向。很长一段时间以来,它对我来说效果很好,公司几乎在所有项目中都在使用它。它已被制成一个 nuget 包,以便于设置。 http://www.nuget.org/packages/RedirectRules/

于 2014-09-30T08:44:35.887 回答
1

我相信我现在真的找到了答案。我解决了一段时间,最后又遇到了另一个问题,再次是 www 与非 www。它根本没有做任何事情。

所以我最终把它放在最后并进行重定向而不是重写。显然这很好用,为什么?不知道。

cheesemacfly 建议我匹配 on^(.+)$而不是(.*). 我认为它会做同样的事情,但意识到匹配根本不在主机名上,它是之后的一切。对我来说是一个很大的惊喜,但它确实开辟了一个新的可能性:

{URL}我可以简单地使用 match 来引用 match ,而不是 match{HTTP_URL}或几乎相同事物的其他变体{R:1}

自从第一篇文章以来,我已经放了两件事。我在某些规则上设置了条件以排除它们,如果它包含“umbraco”,因为我使用该系统以及我不想应用于后端的大多数规则。我还为 SSL 检查应用了重写映射,因此它会自动将您置于https://http://使用服务器变量{HTTPS}

到目前为止,我还没有发现任何错误,所以我会将其标记为已解决,并为您提供我对规则的最新修订。享受 :)

<rewrite>
    <rules>
        <rule name="WhiteList - resources" stopProcessing="true">
            <match url="^resources/" />
            <conditions logicalGrouping="MatchAll" trackAllCaptures="false" />
            <action type="None" />
        </rule>
        <rule name="SEO - Remove trailing slash" stopProcessing="false">
            <match url="(.*)/$" />
            <conditions>
                <add input="{REQUEST_FILENAME}" matchType="IsFile" negate="true" />
                <add input="{REQUEST_FILENAME}" matchType="IsDirectory" negate="true" />
            </conditions>
            <action type="Rewrite" url="{R:1}" />
            <serverVariables>
                <set name="Redirect" value="true" />
            </serverVariables>
        </rule>
        <rule name="SEO - ToLower" stopProcessing="false">
            <match url="(.*)" ignoreCase="false" />
            <conditions logicalGrouping="MatchAll" trackAllCaptures="false">
                <add input="{URL}" pattern="[A-Z]" ignoreCase="false" />
                <add input="{URL}" pattern="^.*?\.(axd|css|js|jpg|jpeg|png|gif|ashx|asmx|svc).*?$" negate="true" />
                <add input="{URL}" pattern="^.*/(webshop)/.*$" negate="true" />
                <add input="{URL}" pattern="^/umbraco/" negate="true" />
            </conditions>
            <action type="Rewrite" url="{ToLower:{R:1}}" />
            <serverVariables>
                <set name="Redirect" value="true" />
            </serverVariables>
        </rule>
        <rule name="SEO - remove default.aspx" stopProcessing="false">
            <match url="(.*?)/?default\.aspx$" />
            <conditions logicalGrouping="MatchAll" trackAllCaptures="false">
                <add input="{URL}" pattern="^/umbraco/" negate="true" />
            </conditions>
            <action type="Rewrite" url="{R:1}" />
            <serverVariables>
                <set name="Redirect" value="true" />
            </serverVariables>
        </rule>
        <rule name="SEO - Trim aspx" stopProcessing="false">
            <match url="(.*)\.aspx$" />
            <action type="Rewrite" url="{R:1}" />
            <conditions logicalGrouping="MatchAll" trackAllCaptures="false">
                <add input="{URL}" pattern="^/umbraco/" negate="true" />
            </conditions>
            <serverVariables>
                <set name="Redirect" value="true" />
            </serverVariables>
        </rule>
        <rule name="Redirect subdomains with www to non-www" stopProcessing="false">
            <match url="(.*)" />
            <conditions logicalGrouping="MatchAll" trackAllCaptures="false">
                <add input="{HTTP_HOST}" pattern=".*localhost.*" negate="true" />
                <add input="{HTTP_HOST}" pattern="^www\.(.*)\.([^\.]+)\.([^\.]+)$" />
            </conditions>
            <action type="Redirect" url="{MapSSL:{HTTPS}}{C:1}.{C:2}.{C:3}/{R:1}" redirectType="Permanent" />
            <serverVariables>
                <set name="Redirect" value="true" />
            </serverVariables>
        </rule>
        <rule name="Redirect top domains with non-www to www" stopProcessing="false">
            <match url="(.*)" />
            <conditions logicalGrouping="MatchAll" trackAllCaptures="false">
                <add input="{HTTP_HOST}" pattern=".*localhost.*" negate="true" />
                <add input="{HTTP_HOST}" pattern="^([^\.]+)\.([^\.]+)$" />
            </conditions>
            <action type="Rewrite" url="{MapSSL:{HTTPS}}www.{HTTP_HOST}/{R:1}" />
            <serverVariables>
                <set name="Redirect" value="true" />
            </serverVariables>
        </rule>
        <rule name="SEO - non-canonical redirect" stopProcessing="true">
            <match url="(.*)" />
            <conditions>
                <add input="{Redirect}" pattern="true" />
            </conditions>
            <action type="Redirect" url="{R:1}" redirectType="Permanent"/>
            <serverVariables>
                <set name="Redirect" value="false" />
            </serverVariables>
        </rule>
    </rules>
    <rewriteMaps>
        <rewriteMap name="MapSSL" defaultValue="OFF">
            <add key="ON" value="https://" />
            <add key="OFF" value="http://" />
        </rewriteMap>
    </rewriteMaps>
</rewrite>

但是有一个警告:请注意,使用了自定义服务器变量。您不能使用开箱即用的自定义服务器变量。您需要将此变量添加到文件中的<allowedServerVariables/>元素中,该applicationHost.config文件是 IIS 的全局配置文件。( Source ) 如果您使用共享主机(包括 Azure 网站),您可能无法更改此设置。

如果您使用的是 Azure Web 角色,则需要添加一个修改上述配置文件的启动任务。如果不这样做,您将收到 IIS 500 错误。

如果有人对如何使规则变得更好提出建议,仍然欢迎他们。

于 2013-02-06T16:13:46.417 回答