减少链接 URL 重定向 [IIS/Regex/ReWrite]

Posted

技术标签:

【中文标题】减少链接 URL 重定向 [IIS/Regex/ReWrite]【英文标题】:Reduce Chained URL Redirects [IIS/Regex/ReWrite] 【发布时间】:2016-12-03 06:25:09 【问题描述】:

我已经在 IIS/ColdFusion 上实现了一些 URL 重定向组合工作正常,但我无法处理一些正则表达式模式以减少不需要的重定向。

目前 IIS 仅在它在 URL 中找到模板名称时才(最多)处理单个重定向。例如IIS 重定向 URL,例如

http://example.com/index.cfm/something/pretty/?page=1

http://example.com/something/pretty/?page=1

例如,它只是从 URL 中删除模板名称,使其后面的所有内容保持不变。根据我的申请,上面的最终 URL 是有效的。

但此外,如果在最终 URL 中未找到尾部斜杠 (/),ColduFusion 应用程序正在处理这种情况并在末尾附加正斜杠,然后重定向到以正斜杠 (/) 结尾的 URL ) 在查询字符串之前(如果有)。它使用一些逻辑来保持 PATH_INFO 和 QUERY_STRING 完好无损。但这实际上会在以下情况下导致多次重定向。

[INIT] http://example.com/index.cfm/sport/badminton 

[Redirect 1] [IIS-301]  http://example.com/sport/badminton

[Redirect 2] [CF-301]  http://example.com/sport/badminton/

现在我想在 IIS 中处理所有这些并在一个规则中涵盖所有情况,我无法制作(或找到)可以做到这一点的正则表达式模式。

当前的 IIS 重定向模式

^index.cfm/(.*)$ 

我尝试了各种方法以及最简单的方法

^index.cfm/(.*[^/])$

但它不包括带有 QUERY_STRING 的 URL。你可以认为我在制作正则表达式方面真的很天真。

更新 1: 我发现该问题的正确术语是“链式”重定向,并在 moz.com 找到了一篇文章,它处理了我上面提到的同一问题。我想它应该可以工作,虽然我正在根据服务器上的要求更改规则,但我想我应该用我为可能遇到此类问题的其他人找到的东西更新这个问题。我会尽快更新此解决方案来解决我身边的问题。

【问题讨论】:

【参考方案1】:

很抱歉,我在这里无法得到答案,但是当我更新上述关于 moz.com 的一篇文章的问题时,我已经实施了这种方法并成功地从链式/多重重定向中恢复。

以前我们的 Web 应用程序支持以下 URL

https://www.example.com/index.cfm/something/pretty/

我们在 IIS 中使用 URL 重写并从 URL 中删除 index.cfm。但是我们遇到了麻烦,有多个/链接的重定向从非 https、非 www 或没有尾随斜杠等重定向。

https://moz.com/blog/what-every-seo-should-know-about-iis#chaining

阅读完上面的文章后,我在 IIS 上实现了以下规则集,这些规则现在处理了我们之前在 IIS 和 ColdFusion 上分别处理的所有情况。

<rules>
<!-- rewrite url to furnish with prefix(_) to better match individual parts -->
<rule name="Remove index.cfm" stopProcessing="false">
    <match url="(.*?)/?index\.cfm/(.*)$" />
    <conditions logicalGrouping="MatchAll" trackAllCaptures="false">
        <add input="HTTP_METHOD" pattern="GET" />
    </conditions>
    <action type="Rewrite" url="_R:2" />
</rule>
<rule name="Add Trailing Slash" stopProcessing="false">
    <match url="(.*[^/])$" />
    <conditions logicalGrouping="MatchAll" trackAllCaptures="false">
        <add input="REQUEST_FILENAME" matchType="IsDirectory" negate="true" />
        <add input="REQUEST_FILENAME" matchType="IsFile" negate="true" />
    </conditions>
    <action type="Rewrite" url="_R:1/" />
</rule>
<rule name="ToLower Everything in URL" enabled="true" stopProcessing="false">
    <match url="(.*)" ignoreCase="false" />
    <conditions logicalGrouping="MatchAll" trackAllCaptures="false">
        <add input="HTTP_METHOD" pattern="GET" />
        <add input="R:1" pattern="[A-Z]" ignoreCase="false" />
    </conditions>
    <action type="Rewrite" url="_ToLower:R:1" />
</rule>
<!-- Now redirect the final prefix-furnished URL  -->       
<!-- match if there is at least one (_) at the start of the furnished URL. Redirect to the final URL -->    
<rule name="http[non www] to https[www] redirect" stopProcessing="true">
    <match url="^(_*)(.*)" />
    <conditions logicalGrouping="MatchAll" trackAllCaptures="false">
        <add input="HTTP_HOST" pattern="^www\.yoursite\.com$" negate="true" />
        <add input="HTTP_METHOD" pattern="GET" />
        <add input="SERVER_PORT" pattern="80" />  
    </conditions>
    <action type="Redirect" url="https://www.example.org/R:2" />
</rule>
<rule name="http[www] to https[www] redirect" stopProcessing="true">
    <match url="^(_*)(.*)" />
    <conditions logicalGrouping="MatchAll" trackAllCaptures="false">
        <add input="HTTP_METHOD" pattern="GET" />
        <add input="SERVER_PORT" pattern="80" />  
    </conditions>
    <action type="Redirect" url="https://www.example.org/R:2" />
</rule>
<rule name="https[non www] to https[www] redirect" stopProcessing="true">
    <match url="^(_*)(.*)" />
    <conditions logicalGrouping="MatchAll" trackAllCaptures="false">
        <add input="HTTP_HOST" pattern="^www\.yoursite\.com$" negate="true" />
        <add input="HTTP_METHOD" pattern="GET" />
        <add input="SERVER_PORT" pattern="443" /> 
    </conditions>
    <action type="Redirect" url="https://www.example.org/R:2" />
</rule>
<!-- this rule is supposed to run final redirect if non above redirect rules occured -->
<rule name="http// redirect" enabled="true" stopProcessing="true">
    <match url="^(_+)(.*)" />
    <conditions logicalGrouping="MatchAll" trackAllCaptures="false">
        <add input="HTTP_METHOD" pattern="GET" />
    </conditions>
    <action type="Redirect" url="R:2" />
</rule>

<!-- now after failing/running all rules above when the IIS reaches at this point, it's the fully validated/funrished URL that qualifies to serve with response. Rewrite the URL to run index.cfm as a template -->
<rule name="URL ReWrite" enabled="true" stopProcessing="true">
    <match url="^(.*)$" />
    <conditions logicalGrouping="MatchAll" trackAllCaptures="false">
        <add input="REQUEST_FILENAME" matchType="IsFile" negate="true" />
        <add input="REQUEST_FILENAME" matchType="IsDirectory" negate="true" />
        <add input="REQUEST_FILENAME" pattern="/admin" negate="true" />
    </conditions>
    <action type="Rewrite" url="index.cfm/R:1" />
</rule>

这些规则严格按照我们希望将所有请求路由到 [https] 的要求,您必须查看上面的 moz.com 文章以供参考。

希望这可以帮助其他人。

【讨论】:

我在 SO 上看到了使用 moz 文章的其他示例,但这是最好的示例。我没有使用coldfusion,但是您的问题和答案与整个IIS 重写非常相关。此外,您将 http/https 和 www/non-www 排列分开的事实比我见过的任何组合它们的尝试都提供了更多的清晰度。您的规则名称也很有用。谢谢!

以上是关于减少链接 URL 重定向 [IIS/Regex/ReWrite]的主要内容,如果未能解决你的问题,请参考以下文章

WordPress 链接全部重定向到双 URL

从动态链接接收 Firebase 重定向 URL

链接中的 URL 片段和 JSF 中的 ajax 重定向

为啥 IE10 会删除外部重定向链接上的 URL 哈希标记

抓取重定向的目标链接

Android WebView 不加载自动重定向 url