一个重定向来统治它们

时间:2013-02-05 12:25:37

标签: iis redirect url-rewriting seo url-redirection

在iis.net论坛上尝试help a fellow developer之后,我开始寻找更好的方法来进行重定向。因此我最终得到了this article.

我采取了很多这些想法并开始实施我自己的版本。一切似乎都运转正常,但我在路上碰了一下,希望你能帮忙。

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

我的想法是测试网址,如果我发现它有问题,我会重写网址并让它继续,而不是立即重定向。如果在任何时候我重写了url,我将自定义服务器变量“Redirect”设置为true。然后最后,我测试我的自定义服务器变量是否为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}并且它们似乎都会出现相同的错误,这有点令人讨厌。

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

2 个答案:

答案 0 :(得分:1)

我相信我现在确实找到了答案。我已经解决了一段时间,最后又出现了另一个问题,再次使用www与非www。它根本没有做任何事情。

所以我最终将它放在最后并进行重定向而不是重写。显然工作正常,为什么?不知道......

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

而不是匹配{URL},{HTTP_URL}或其他一些同样的变体。我可以简单地用{R:1}

来引用匹配

自第一篇文章以来,我已经提出了两件事。如果它包含umbraco,当我使用该系统并且我不想将大多数规则应用于后端时,我会对某些规则进行排除以排除它们。我还为SSL检查应用了重写映射,因此它使用服务器变量{HTTPS}自动将您转到https://或http://

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

<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错误。

如果有人对可以使规则变得更好的建议有所建议,那么他们仍然会受到欢迎。

答案 1 :(得分:1)

这最终变成了版本1,我已经改进了它以避免服务器变量。 现在我使用一系列重写规则将url转换为我喜欢的东西,附加下划线。 然后剥离下划线然后重定向。 它已经很好地适用于我很长一段时间了,几乎所有项目都被公司使用。 它已被制作成一个nuget包,便于安装。 http://www.nuget.org/packages/RedirectRules/