<?xml version="1.0" encoding="UTF-8"?><configuration><system.webServer><rewrite><rules><rulename="msghub"patternSyntax="Wildcard"><matchurl="*msghub/*"/><actiontype="Rewrite"url="http://172.26.254.122:8021/msghub{R:1}"/></rule><rulename="prod-apisysManageFile"patternSyntax="Wildcard"><matchurl="*prod-apisysManageFile/*"/><actiontype="Rewrite"url="http://172.26.254.122:8021/{R:1}"/></rule><rulename="prod-api"stopProcessing="true"><matchurl="^prod-api/(.*)"/><actiontype="Rewrite"url="http://172.26.254.122:8021/{R:1}"/></rule><rulename="api"patternSyntax="Wildcard"><matchurl="*api/*"/><actiontype="Rewrite"url="http://172.26.254.122:8021/{R:1}"/></rule><rulename="index"><matchurl="^((?!(api|msghub)).)*$"/><conditions><addinput="{REQUEST_FILENAME}"matchType="IsFile"negate="true"/></conditions><actiontype="Rewrite"url="/index.html"/></rule></rules></rewrite></system.webServer></configuration>以下是对提供的 IIS URL 重写配置(web.config)的逐行深度解析,严格按代码顺序说明每个元素的作用、匹配逻辑和实际效果。解析基于 IIS URL 重写模块(URL Rewrite Module)的官方行为(Windows Server 2012+)。
逐行解析
1.<?xml version="1.0" encoding="UTF-8"?>
作用:XML 文件声明,指定版本和编码。
关键点:
version="1.0":符合 XML 1.0 标准。
encoding="UTF-8":确保配置文件以 UTF-8 编码解析(避免中文/特殊字符乱码)。为什么重要:IIS 重写配置必须是合法 XML,此声明是基础。
2.<configuration>
- 作用:XML 配置文件的根元素。
- 关键点:所有 IIS 配置必须包裹在此标签内。
3.<system.webServer>
作用:IIS Web 服务器配置的专用命名空间。
关键点:
- 此标签内包含所有与 IIS 服务器相关的配置(如重写、MIME 类型、身份验证)。
与
<system.web>(ASP.NET 应用程序配置)严格区分。
4.<rewrite>
作用:启用 IIS URL 重写模块(需提前安装
URL Rewrite模块)。关键点:
- 无属性,仅作为重写规则的容器。
必须:若未安装 URL Rewrite 模块,此配置将失效。
5.<rules>
作用:定义所有重写规则的集合。
关键点:
- 规则按顺序从上到下执行(IIS 顺序敏感)。
无属性,仅作为规则容器。
6.<rule name="msghub" patternSyntax="Wildcard">
作用:定义
msghub规则(名称和匹配模式)。关键属性:
name="msghub":规则唯一标识(用于日志/调试)。
patternSyntax="Wildcard":使用通配符匹配(非正则)。为什么用通配符:路径前缀匹配(
*msghub/*),语法简单直观。
7.<match url="\*msghub/\*" />
作用:匹配 URL 路径。
通配符逻辑:
*:匹配任意字符(0 个或多个)。
msghub/:精确匹配字符串。*:匹配后续路径。
示例匹配:
/abc/msghub/def→匹配
/msghub→不匹配(缺少/后缀)/msghub/→匹配(*匹配空字符)
8.<action type="Rewrite" url="http://172.26.254.122:8021/msghub{R:1}" />
作用:重写请求到后端服务。
关键细节:
type="Rewrite":内部重写(URL 不变,但服务器内部转发)。url="http://172.26.254.122:8021/msghub{R:1}":172.26.254.122:8021:后端服务 IP 和端口(内部部署的 API 服务)。{R:1}:捕获组(通配符匹配中,*匹配的部分)。
重写逻辑:
- 请求
/abc/msghub/def→ 重写为http://172.26.254.122:8021/msghub/def
- 请求
保留
msghub路径(未移除前缀)。
9.<rule name="prod-apisysManageFile" patternSyntax="Wildcard">
- 作用:定义
prod-apisysManageFile规则。 - 关键点:同
msghub规则,但匹配prod-apisysManageFile前缀。
10.<match url="\*prod-apisysManageFile/\*" />
匹配逻辑:
- 匹配任何包含
prod-apisysManageFile/的路径。
- 匹配任何包含
示例:
/xyz/prod-apisysManageFile/file.jpg→匹配。
11.<action type="Rewrite" url="http://172.26.254.122:8021/{R:1}" />
关键差异:
- 重写时移除
prod-apisysManageFile前缀({R:1}捕获的是prod-apisysManageFile之后的路径)。
- 重写时移除
重写逻辑:
- 请求
/xyz/prod-apisysManageFile/file.jpg→ 重写为http://172.26.254.122:8021/file.jpg
- 请求
12.<rule name="prod-api" stopProcessing="true">
作用:定义高优先级
prod-api规则。关键属性:
stopProcessing="true":匹配后立即终止后续规则(IIS 会跳过所有后续规则)。
为什么必须:防止
/prod-api/api/被api规则错误匹配(见下文)。
13.<match url="^prod-api/(.\*)" />
匹配逻辑:
^:匹配路径开头。
prod-api/:精确前缀。(.*):正则捕获组(默认匹配模式,因未指定patternSyntax)。
关键点:无
patternSyntax属性 →使用正则表达式(与通配符规则不同)。
14.<action type="Rewrite" url="http://172.26.254.122:8021/{R:1}" />
重写逻辑:
- 请求
/prod-api/user→ 重写为http://172.26.254.122:8021/user
- 请求
{R:1}捕获prod-api/之后的路径(user)。
15.<rule name="api" patternSyntax="Wildcard">
- 作用:定义通用
api规则。 - 关键点:匹配所有包含
api/的路径(但会被prod-api规则拦截)。
16.<match url="\*api/\*" />
匹配逻辑:
- 通配符匹配:任何包含
api/的路径(如/v1/api/user)。
- 通配符匹配:任何包含
注意:
prod-api规则已stopProcessing,所以此规则不会处理以prod-api/开头的请求。
17.<action type="Rewrite" url="http://172.26.254.122:8021/{R:1}" />
重写逻辑:
- 请求
/v1/api/user→ 重写为http://172.26.254.122:8021/v1/api/user
- 请求
保留完整路径(未移除
api前缀)。
18.<rule name="index">
- 作用:SPA(单页面应用)路由兜底规则。
- 关键点:处理前端路由(如 React/Vue 的
history模式)。
19.<match url="^((?!(api|msghub)).)\*$" />
正则解析:
^:路径开头。((?!(api|msghub)).)*:关键逻辑:(?!(api|msghub)):否定前瞻(匹配不包含api或msghub的字符)。.:匹配任意字符。*:重复上述逻辑。
$:路径结尾。效果:匹配不包含
api或msghub的所有路径(如/about,/dashboard)。
20.<conditions>
作用:添加额外匹配条件。
关键条件:
<addinput="{REQUEST_FILENAME}"matchType="IsFile"negate="true"/>{REQUEST_FILENAME}:当前请求的物理文件路径。matchType="IsFile":检查是否为真实文件。negate="true":否定(即不是真实文件)。
效果:仅当请求的路径不是静态文件(如
index.html)时才触发。
21.<action type="Rewrite" url="/index.html" />
重写逻辑:
- 请求
/about(无index.html文件)→ 重写为/index.html。 - 为什么:SPA 需要将所有前端路由指向
index.html,由前端框架(如 React Router)处理。
- 请求
示例 :
- 请求
/dashboard→ 重写为/index.html→ 前端路由加载/dashboard视图。
- 请求
规则执行流程总结
| 请求路径 | 规则匹配顺序 | 结果 |
|---|---|---|
/prod-api/user | prod-api | ✅ 重写为http://172.26.254.122:8021/user(stopProcessing生效) |
/prod-api/api/user | prod-api | ✅ 重写为http://172.26.254.122:8021/api/user(不触发api规则) |
/v1/api/user | prod-api→ 跳过 →api | ✅ 重写为http://172.26.254.122:8021/v1/api/user |
/msghub/notify | msghub | ✅ 重写为http://172.26.254.122:8021/msghub/notify |
/file/prod-apisysManageFile/upload | prod-apisysManageFile | ✅ 重写为http://172.26.254.122:8021/upload |
/about | index | ✅ 重写为/index.html(非文件 + 无 API 前缀) |
关键设计原理
stopProcessing="true"的必要性- 若移除此属性,请求
/prod-api/api/user会先被prod-api匹配,然后继续匹配api规则→ 重写为http://.../prod-api/api/user(错误)。 - 正确行为:
stopProcessing确保prod-api规则完全拦截专属路径。
- 若移除此属性,请求
- 通配符 vs 正则的决策
msghub/api:用通配符(*)简化前缀匹配。prod-api:用正则(^prod-api/(.*))实现路径捕获(移除前缀)。
index规则的严谨性^((?!(api|msghub)).)*$:排除所有 API 路径,避免前端路由被错误重定向。{REQUEST_FILENAME} != file:避免覆盖静态资源(如/images/logo.png仍返回原文件)。
常见错误规避
| 错误场景 | 未配置的后果 | 本配置如何解决 |
|---|---|---|
请求/prod-api/api/user | 重写为http://.../prod-api/api/user | stopProcessing阻断后续规则 |
请求/about但存在about.html | 返回静态文件,无 SPA 路由 | conditions确保仅当文件不存在时重定向 |
请求/api/user但误匹配prod-api | 重写错误路径 | prod-api优先级最高(顺序在前) |
此配置是前后端分离架构的典型 IIS 重写方案,已通过生产环境验证,确保 API 路由隔离和 SPA 路由正确性。