首页 > 解决方案 > 将多个 301 重定向合并为一个用于 ASP.NET URL 重写模块

问题描述

我试图将 Global.asax 中实现的复杂重定向逻辑移动到经典 ASP.NET 网站中 IIS URL 重写模块的一组规则中。很快,逻辑必须重定向请求,如

{http|https}://[www.]ourdomain.com/[Home/]Products/old-product-name/page.aspx

https://ourdomain.com/new-product-name/

(可选和可变部分在方括号和大括号中)。

我使用 URL 重写规则实现的前 3 个主要内容如下:

<rule name="Redirect to HTTPS">
    <match url=".*" />
    <conditions>
        <add input="{HTTPS}" pattern="off" ignoreCase="true" />
    </conditions>
    <action type="Redirect" url="https://{HTTP_HOST}{REQUEST_URI}" redirectType="Permanent" />
</rule>
<rule name="Canonical Host Name">
    <match url="(.*)" />
    <conditions>
        <add input="{HTTP_HOST}" negate="true" pattern="^ourdomain\.com$" />
    </conditions>
    <action type="Redirect" url="https://ourdomain.com/{R:1}" redirectType="Permanent" />
</rule>
<rule name="Default Page">
    <match url="(.*)default.aspx" />
    <conditions>
        <add input="{REQUEST_URI}" negate="true" pattern="-default.aspx$" />
    </conditions>
    <action type="Redirect" url="{R:1}" redirectType="Permanent" />
</rule>

这些规则允许将请求重定向http://www.ourdomain.com/product-name/default.aspxhttps://ourdomain.com/product-name.

但是,浏览器开发人员工具报告说这种转换会导致 301 重定向。我试图在互联网上找到这个重定向链问题的解决方案,并找到了这个帖子。读完之后,我设法重新编码我的规则,使最后一个带有 URL 重写的 301 重定向:

<rule name="Redirect to HTTPS">
    <match url=".*" />
    <conditions>
        <add input="{HTTPS}" pattern="off" ignoreCase="true" />
    </conditions>
    <action type="Rewrite" url="_{REQUEST_URI}" redirectType="Permanent" />
</rule>
<rule name="Canonical Host Name">
    <match url="(.*)" />
    <conditions>
        <add input="{HTTP_HOST}" negate="true" pattern="^ourdomain\.com$" />
    </conditions>
    <action type="Rewrite" url="_{R:1}" redirectType="Permanent" />
</rule>
<rule name="Default Page">
    <match url="(.*)default.aspx" />
    <conditions>
        <add input="{REQUEST_URI}" negate="true" pattern="-default.aspx$" />
    </conditions>
    <action type="Rewrite" url="_{R:1}" redirectType="Permanent" />
</rule>

<rule name="FINAL REDIRECT" stopProcessing="true">
    <match url="^(_+)(.*)" />
    <conditions logicalGrouping="MatchAll" trackAllCaptures="false">
        <add input="{HTTP_METHOD}" pattern="GET" />
    </conditions>
    <action type="Redirect" url="https://ourdomain.com{R:2}" />
</rule>

但是,这种方法看起来不自然。由于这些带有下划线字符的变通方法,很难添加新规则。也许,一个请求的这样多次重写操作可能会影响网站性能。

对于 URL Rewrite 模块的 301 重定向链问题,还有另一种更优雅的解决方案吗?

标签: asp.netredirectiisurl-rewrite-module

解决方案


这不是 IIS Url Rewrite 的限制,而是 Web 的工作方式。重定向向浏览器发送一个标头,告诉它应该导航到另一个地方。如果您有 3 条规则适用于相同的原始请求,并且 3 条规则应用了重定向,那么无论您如何操作,您总是会获得 3 条重定向:IIS Url Rewrite、Apache .htaccess 或您自己的自定义代码。

您实现的解决方案是一个“补丁”,用于将多个重定向更改为服务器中的内部重写,以及这些特殊重写的最终“捕获”,以在最后将它们转换为唯一的重定向(顺便说一句,如果您有任何真实页面使用此额外规则,_您将无法访问它)。这还不错,不会影响你的表现,但它很难看。

我不是 SEO 专家,但我认为最近通过 301 链接达到最终类似 URL 的事情根本不会损害您的 SEO ,如果这就是您所担心的(请特别阅读最后一部分)。作为 301 重定向,它们只会影响用户的第一次访问,因此可能不会影响您的加载时间或转换。

但是,如果您想避免这种情况,请尝试为您的目的制定一个规则,一次完成所有转换。在你的情况下,你想改变这个:

{http|https}://[www.]ourdomain.com/[Home/]Products/old-product-name/page.aspx

(我猜/Home/有时会出现或不出现)

进入这个:

https://ourdomain.com/new-product-name/

然后你可以使用这个单一的规则:

<rule name="New URLs!!" stopProcessing="true">
    <match url="^(Home/){0,1}Products/(.+?/).+.aspx" />
    <conditions logicalGrouping="MatchAny">
        <add input="{HTTPS}" pattern="off" ignoreCase="true" />
        <add input="{HTTP_HOST}" negate="true" pattern="^ourdomain\.com$" />
    </conditions>
    <action type="Redirect" url="https://ourdomain.com/{R:2}" redirectType="Permanent" />
</rule>

您将使用一条规则转换所有内容(因此,只有一个重定向)。匹配 URL 部分中的正则表达式将识别这种特定类型的 URL(旧产品 URL),并且条件(匹配其中任何一个)将处理 HTTPs 和域更改。这stopProcessing="true"将保持其他规则的作用,并且您将控制这种特定类型的 URL。

请注意,我没有测试过这条规则,也许它有一些小问题。但你明白了……

在此之后,您需要额外的规则来处理其他不太具体的 URL,例如您的通用 HTTP 到 HTTPS 或规范域规则。但是如果你想解决,这将在一个步骤中实现你想要的。


推荐阅读