如何在web.config中捕获并重定向.cfm文件且排除index.cfm?
问题分析与规则修正
需求回顾
- 禁止直接访问
about.cfm这类文件,永久重定向到对应/about路径 - 允许访问
index.cfm(避免触发无限重定向) - 允许访问
/ajax/目录下的.cfm文件 - 已配置美化URL规则,将
/about重写为index.cfm?p=about
现有规则的核心问题
1. 禁止直接访问的正则规则逻辑错误
原规则:
<rule name="don't allow direct access to .cfm pages" stopProcessing="true"> <match url="^(.+[^/ajax/]/)?([^/]+[^index]).cfm$" /> <action type="Redirect" redirectType="Permanent" url="{R:1}/{R:2}" /> </rule>
问题点:
[^index]是排除单个字符(i、n、d、e、x),而非排除整个index字符串,导致index.cfm(尤其是带查询参数的index.cfm?p=contact)被错误匹配- 分组捕获逻辑混乱,访问
contact.cfm时会生成错误的重定向路径,进而触发美化规则循环,最终出现重复p=index的异常URL
2. 规则执行顺序引发循环
美化URL规则会将/contact重写为index.cfm?p=contact,若禁止规则错误匹配了index.cfm,会再次触发重定向,形成无限循环。
修正后的规则方案
第一步:修复禁止直接访问的规则
<rule name="Block direct access to non-index, non-ajax CFM files" stopProcessing="true"> <!-- 匹配所有.cfm文件,排除/ajax/目录和index.cfm --> <match url="^(?!ajax/)(?!index\.cfm$).+\.cfm$" /> <action type="Redirect" redirectType="Permanent" url="/{C:1}" /> <conditions> <!-- 提取.cfm后缀前的文件名 --> <add input="{URL}" pattern="^/?(.+)\.cfm$" /> </conditions> </rule>
逻辑说明:
(?!ajax/):负向预查,直接排除/ajax/开头的路径(?!index\.cfm$):负向预查,精确排除index.cfm请求- 通过条件提取文件名,重定向到干净的
/{文件名}路径
第二步:调整规则执行顺序
必须先执行禁止直接访问的规则,再执行美化URL规则,确保重写后的index.cfm不会被错误匹配。
美化URL规则(保留原逻辑,确保顺序正确):
<rule name="Prettify URL" stopProcessing="true"> <match url="^(.+/)?([^/]+)$" /> <conditions logicalGrouping="MatchAll"> <add input="{REQUEST_FILENAME}" matchType="IsFile" ignoreCase="false" negate="true" /> <add input="{REQUEST_FILENAME}" matchType="IsDirectory" ignoreCase="false" negate="true" /> </conditions> <action type="Rewrite" url="{R:1}index.cfm?p={R:2}" appendQueryString="false" /> </rule>
验证要点
- 访问
/contact.cfm应直接重定向到/contact /index.cfm、/ajax/test.cfm可正常访问,无重定向- 不会出现重复
p=index的循环重定向问题
内容的提问来源于stack exchange,提问作者Melissa N.
相关产品推荐
相关产品推荐

