# IIS URL Rewrite：不会循环的重定向

> 安装 URL Rewrite，写 HTTP→HTTPS 和规范主机名规则，理解规则顺序与 stopProcessing，并在反代后面正确测试 301。

**测试环境**

- 版本号: 26100.33650
- 版本: Standard / Datacenter
- 架构: x64
- 证据: E1
- 核验日期: 2026-10-29

## 一句话结论

URL Rewrite 是 **IIS 扩展**，不是内置角色服务。它按 `web.config` 里的规则重写或重定向请求。

适合：

- HTTP → HTTPS；
- `www` ↔ 裸域规范主机名；
- 去掉尾斜杠/旧路径；
- 短而确定的 URL 映射。

不要拿它当反向代理。反代是 ARR；重写只改变 IIS 服务的 URL，代理是把请求转给另一台服务器。

## 安装与验证

从微软下载 x64 URL Rewrite 模块，安装后：

```powershell
Get-WebGlobalModule -Name RewriteModule
```

没有这个模块，下面的规则会被忽略，或站点 500.19 “找不到模块”。

## HTTP → HTTPS

```xml
<configuration>
  <system.webServer>
    <rewrite>
      <rules>
        <rule name="HTTP to HTTPS" stopProcessing="true">
          <match url="(.*)" />
          <conditions>
            <add input="{HTTPS}" pattern="^OFF$" />
          </conditions>
          <action type="Redirect"
                  url="https://{HTTP_HOST}/{R:1}"
                  redirectType="Permanent" />
        </rule>
      </rules>
    </rewrite>
  </system.webServer>
</configuration>
```

- `{R:1}` 是 `(.*)` 捕获的路径。
- `redirectType="Permanent"` 发 **301**；测试时用 `Found`（302）。
- `stopProcessing="true"` 停止后续规则。

测试：

```powershell
curl.exe -I http://lab.local/
curl.exe -I https://lab.local/
```

第一条应返回 `301` 和 `Location: https://...`；第二条应 `200`，不能再次跳转。

## 规范主机名

```xml
<rule name="Canonical host" stopProcessing="true">
  <match url="(.*)" />
  <conditions>
    <add input="{HTTP_HOST}" pattern="^www\.example\.com$" />
  </conditions>
  <action type="Redirect" url="https://example.com/{R:1}" redirectType="Permanent" />
</rule>
```

规范主机名规则放在通用路径规则**之前**。把所有请求都跳到 `https://example.com` 的规则，也可能抓到健康检查路径；反代改写 `Host` 时会循环。

## 反代后的循环

在 ARR/Nginx 后面，IIS 可能看到 `HTTP`，即使客户端用的是 HTTPS。天真的 `{HTTPS} = OFF` 规则会无限重定向。

先修信任边界：

- 代理终止 TLS，并转发 `X-Forwarded-Proto`；
- ARR 保留 host/proto；
- 再给转发头加条件，或排除代理的健康检查路径。

不要用“全局关掉 HTTPS 跳转”来修循环。

> **警告: 301 会被缓存**
>
> 浏览器和 CDN 会缓存永久重定向。先用 302 测，用隐私窗口或 `curl`，免得坏 301 挂几小时。

## 规则顺序与作用域

- 规则从上到下执行；`stopProcessing` 停止链。
- 站点根 `web.config` 会继承到应用；子应用可以清除/覆盖。
- 条件是 AND；多个 `<add>` 都要匹配。
- `{HTTP_HOST}` 在非默认端口时可能带端口；带端口场景要小心。

## 验证与回滚

```powershell
Get-WebConfigurationProperty -PSPath 'MACHINE/WEBROOT/APPHOST' `
  -Filter 'system.webServer/rewrite/rules' -Name '.'
```

保存旧 `web.config`，用 `curl -I` 测；链不对就删规则。URL Rewrite 不能替代站点配置备份。

## 实验室边界

本页 E1：实验室只拍了 IIS 绑定/应用池，没有安装 URL Rewrite 或测 HTTPS 跳转。XML 是起点，要在目标 Server 2025 build 上验证。

## 来源

- [Microsoft Learn — URL Rewrite 配置](https://learn.microsoft.com/zh-cn/iis/extensions/url-rewrite-module/url-rewrite-module-configuration-reference)
- [Microsoft Learn — 创建重写规则](https://learn.microsoft.com/zh-cn/iis/extensions/url-rewrite-module/creating-rewrite-rules-for-the-url-rewrite-module)
- [Microsoft Learn — URL Rewrite 与 ARR](https://learn.microsoft.com/zh-cn/iis/extensions/url-rewrite-module/reverse-proxy-with-url-rewrite-v2-and-application-request-routing)

---

来源页面: https://winbook.fyi/zh/server/web/iis-url-rewrite/
