URL 重写规则似乎是重定向而不是重写

URL Rewrite rules appear to be redirecting instead of rewriting

我正在使用 IIS URL 重写 2.0 模块来创建一个 URL 始终指向我的应用程序的最新版本。我配置如下:

<rule name="Latest" stopProcessing="true">
    <match url="^latest(.*)" />
    <action type="Rewrite" url="1.1{R:1}" />
</rule>

的目的是,如果某些内容转到 /latest/*,则所有 URL 都将重写为 /1.1/*。例如 /latest/index.html 应该变成 /1.1/index.html.

这在我请求文件时有效,例如:

/latest/index.html - works
/latest/js/app.js - works

但是这不起作用:

/latest

因为 index.html 是默认文档,我希望它重写为 /1.1/index.html,但实际上它似乎做了 重定向 。例如,如果我在浏览器地址栏中键入以下内容:

http://<domain>/latest

并按 ENTER,它变为:

http://<domain>/1.1

好像重定向了。它仍然有效,但我不希望 URL 改变(因此我使用 Rewrite 而不是 Redirect)。知道为什么吗?我的规则有问题吗?

这可能是您遇到的问题:

IIS generates courtesy redirect when folder without trailing slash is requested

(尽管该文章是关于 IIS6 的,但 IIS7+ 的行为方式相同,而且您似乎无法禁用此行为。)

在您的现有规则之前添加一个仅匹配 /latest 的规则(没有尾部斜线):

<rewrite>
    <rules>
        <rule name="Latest1" stopProcessing="true">
            <match url="^latest$" />
            <action type="Rewrite" url="1.1/" />
        </rule>
        <rule name="Latest2" stopProcessing="true">
            <match url="^latest(.*)" />
            <action type="Rewrite" url="1.1{R:1}" />
        </rule>
    </rules>
</rewrite>

可能有一种更优雅的方式,它按照罐头上的说明进行操作。

您可能需要硬重新加载页面,因为您的浏览器可能会缓存重定向,您始终可以在 "incognito mode" 中进行测试,它永远不会在会话之间保存永久重定向。

当您请求 URL /latest 时,您的规则会将其重写为 /1.1。由于 /1.1 匹配现有目录而不是文件,因此 IIS 以礼节性重定向 as described here 进行响应。 IIS 使用重写的 URL 因为它看不到原来的 URL.


与其通过两个 URL(/latest/latest/)提供相同的内容,我建议您通过您的规则模拟相同的行为。如果请求的 URL 是 /latest 它应该首先重定向到 /latest/ 然后重写:

<rule name="Latest: force trailing slash" stopProcessing="true">
    <match url="^latest$" />
    <action type="Redirect" url="latest/" redirectType="Found" />
</rule>
<rule name="Latest: rewrite" stopProcessing="true">
    <match url="^latest/(.*)" />
    <action type="Rewrite" url="1.1/{R:1}" />
</rule>