IIS URL重写模块(URL Rewrite Module)是Windows服务器上处理请求路径的重要扩展组件。它的作用是在请求进入IIS处理管线后、尚未交给具体资源之前,根据预设规则改变请求的URL。比如把http请求强制跳转到https、把动态地址伪装成静态地址、根据域名或请求头做反向代理等。模块安装后,IIS管理器会多出URL重写图标,但真正的配置保存在站点的web.config文件中,通常位于C:\inetpub\wwwroot\web.config,也可以直接在服务器级别写入C:\Windows\System32\inetsrv\config\applicationHost.config。本文重点讲解规则编写思路,所有示例均以站点级别配置为主。

规则的基本结构与匹配顺序
一条完整的URL重写规则由外层<rewrite>节点包裹,内部包含<rules>规则集合,每个<rule>代表一条具体处理逻辑。在<rule>下通常有三个关键子元素:<match>定义要匹配的URL路径模式,<conditions>定义额外判断条件,<action>定义匹配成功后执行的操作。下面是一个最基础的规则框架。
<configuration>
<system.webServer>
<rewrite>
<rules>
<rule name="Example Rule" stopProcessing="false">
<match url="^old/(.*)" />
<action type="Rewrite" url="new/{R:1}" />
</rule>
</rules>
</rewrite>
</system.webServer>
</configuration>
其中的name属性只是给管理员看的标识,不影响执行逻辑;stopProcessing属性控制是否在命中当前规则后停止处理后续规则。IIS默认从第一条规则开始逐行匹配,如果某条规则的操作带有stopProcessing="true",并且匹配成功,那么后面的规则就不会再执行。这个顺序特性非常关键,很多规则失效的原因就是把宽泛规则放在了前面,导致后面更精确的规则永远得不到机会。因此规划规则集时,应当先放特殊场景,再放通用兜底。
URL重写模块的匹配对象是URL路径部分,不包含域名、端口和查询字符串。例如请求地址是http://www.ipipp.com/products/list.aspx?id=5,<match url>实际看到的是products/list.aspx。如果想要判断域名或查询字符串,就必须使用<conditions>中的{HTTP_HOST}、{QUERY_STRING}等服务器变量。这个边界区分常常被忽略,写规则时一旦混淆路径和完整URL,正则表达式就很容易出错。
正则表达式与服务器变量的配合
URL重写模块使用.NET正则表达式语法,<match url>里的pattern属性负责定义匹配规则。常用的模式包括^表示开头、$表示结尾、.*表示任意字符、[0-9]+表示连续数字等。括号用于捕获分组,捕获结果可以在action中通过{R:1}、{R:2}引用,R代表Rule,数字代表第几个捕获组。例如模式^products/([0-9]+)$可以把products/128中的128提取出来,再重写到product.aspx?id={R:1}。
服务器变量则通过花括号形式在条件或操作中调用,常用的有{HTTPS}、{HTTP_HOST}、{REQUEST_URI}、{QUERY_STRING}。条件节点<conditions>支持logicalGrouping属性,取值MatchAll表示所有条件同时成立,MatchAny表示任一条件成立即可。每个<add>条件中的input可以是服务器变量或其他自定义值,pattern是该条件要匹配的正则。条件也支持捕获组,引用时使用{C:1}、{C:2},C代表Condition。下面这个例子判断请求使用的不是https时才执行重定向。
<rule name="HTTP to HTTPS" stopProcessing="true">
<match url="(.*)" />
<conditions logicalGrouping="MatchAll">
<add input="{HTTPS}" pattern="off" />
</conditions>
<action type="Redirect" url="https://{HTTP_HOST}/{R:1}" redirectType="Permanent" />
</rule>
正则虽然灵活,但也要注意性能。尽量避免使用.*开头的无限吞并模式,因为这会增加回溯成本。更推荐使用相对精确的字符组,比如[^/]+表示不包含斜杠的一段内容。在需要忽略大小写时,可以给<match>添加ignoreCase="true"属性。对于URL中包含中文字符或特殊符号的情况,IIS会自动处理编码,正则匹配通常基于解码后的路径,不必手动处理百分号编码。
常见应用场景与配置示例
第一个典型需求是把动态URL改写成静态形式,让用户看不到真实的脚本文件。比如真实请求是/index.php?category=books&id=25,希望对外展示为/books/25。这时入口规则要匹配books/25这种路径,然后重写到内部处理文件。
<rule name="Rewrite category and id" stopProcessing="true">
<match url="^([a-z]+)/([0-9]+)$" />
<action type="Rewrite" url="index.php?category={R:1}&id={R:2}" appendQueryString="false" />
</rule>
这里appendQueryString="false"表示不要保留原始查询字符串,因为我们已经通过路径生成了新的参数。如果设置成true,原始URL后面带的查询参数会追加到新地址上,可能导致参数重复。另一个常见场景是根据域名做反向代理。IIS需要先安装ARR模块,然后通过URL重写把某个路径转发到内部服务器,配置时要使用type="Rewrite"并配合serverVariables修改HTTP_X_FORWARDED_HOST等值,这里先不展开ARR安装步骤。
还有一个高频用法是给旧网址做301跳转。例如站点从ASP迁移到ASP.NET,旧链接为/article.asp?id=123,新链接为/articles/123。可以写一条规则匹配旧路径,在操作中使用Redirect类型和redirectType="Permanent",这样浏览器和搜索引擎就会更新索引。注意Redirect与Rewrite的区别:Redirect会返回302或301状态码让浏览器重新发起请求,地址栏会变化;Rewrite是服务器内部转发,地址栏保持不变,用户感知不到底层路径。
调试方法与常见错误排查
编写规则时最常遇到的错误包括正则没有匹配到预期内容、条件变量写错、规则顺序错误导致被前面的规则拦截等。IIS提供了失败请求跟踪功能,可以在IIS管理器中开启Failed Request Tracing,然后添加规则专门记录URL重写过程。此外,也可以临时创建一条日志专用规则,把请求重写到某个测试页面并传递原始URL参数,帮助观察最终的匹配结果。
<rule name="Debug rewrite" stopProcessing="false">
<match url="(.*)" />
<action type="Rewrite" url="debug.aspx?original={R:1}" />
</rule>
如果调试发现规则没有生效,第一步要确认URL重写模块是否已经正确安装,可以在IIS管理器站点功能列表中查看是否存在URL重写图标。第二步检查配置是否写在了正确的层级,站点级别的web.config路径应该是C:\inetpub\wwwroot\web.config或者自定义站点目录下的web.config。第三步查看浏览器地址栏和IIS日志,区分请求是被重写还是被重定向。若日志中原始URI没变化但状态码是301,说明发生了重定向;若状态码200但日志显示的是内部路径,说明重写成功。
另一个常见隐患是规则对静态资源产生了影响。例如一个宽泛规则<match url="(.*)" />会把CSS、JS、图片请求也重写到某个处理页面,导致页面样式丢失。解决办法是在条件中排除静态文件扩展名,或者先写一条规则匹配静态资源并设置stopProcessing="true"。规则集的顺序需要结合业务逻辑反复测试,必要时把通用规则放在最后,特殊规则放在前面。最后别忘了备份web.config,修改前复制一份到C:\inetpub\backup\web.config.bak,这样出现严重错误时可以快速恢复。
IIS URL重写URL重写规则web.config修改时间:2026-09-25 01:05:29