使用IIS URL Rewrite与ARR转发至Flask(wfastcgi)时如何移除路径前缀?
问题根源
你的Rewrite规则逻辑本身是对的,但实际转发仍带前缀,大概率是ARR反向代理的默认行为导致的——ARR在转发时可能会保留原始请求的URL路径,而非遵循Rewrite规则里重写后的路径,尤其是没正确开启ARR的反向代理路径重写选项时。
修正步骤
1. 调整URL Rewrite规则(确保逻辑落地)
先确认规则语法没问题,当前规则逻辑正确,但可以补充头信息设置,同时加上参数保留的配置,修改后的规则如下:
<rule name="to dq" enabled="true" stopProcessing="true"> <match url="^digitalquality/(.*)$" /> <action type="Rewrite" url="http://localhost:8081/{R:1}" appendQueryString="true" /> <!-- 可选:添加转发头,帮助Flask识别代理信息 --> <serverVariables> <set name="HTTP_X_FORWARDED_HOST" value="{HTTP_HOST}" /> <set name="HTTP_X_FORWARDED_PREFIX" value="/digitalquality" /> </serverVariables> </rule>
注意:如果要修改serverVariables,得在IIS的URL Rewrite模块里,点击「视图服务器变量」,添加允许修改这两个变量(HTTP_X_FORWARDED_HOST、HTTP_X_FORWARDED_PREFIX),不然会报错。
2. 开启ARR的反向代理路径重写
ARR默认不会完全遵循Rewrite规则的路径,必须手动开启相关设置:
- 打开IIS管理器,找到服务器节点,双击「Application Request Routing Cache」
- 点右侧的「Server Proxy Settings」
- 勾选「Enable proxy」,同时确保「Reverse rewrite host in response headers」和「Rewrite URL」相关选项是启用状态
- 另外,勾选「Preserve client IP in the X-Forwarded-For header」(可选,方便排查日志)
3. 检查Flask站点的web.config(wfastcgi配置)
确保Flask站点的web.config里没有额外的Rewrite规则干扰,wfastcgi的配置要简洁,示例如下:
<system.webServer> <handlers> <add name="Python FastCGI" path="*" verb="*" modules="FastCgiModule" scriptProcessor="C:\Python39\python.exe|C:\Python39\Lib\site-packages\wfastcgi.py" resourceType="Unspecified" requireAccess="Script" /> </handlers> </system.webServer> <appSettings> <add key="WSGI_HANDLER" value="app.app" /> <add key="PYTHONPATH" value="C:\path\to\your\flask\app" /> </appSettings>
别在这个web.config里加多余的Rewrite规则,避免和80端口站点的规则冲突。
4. 确认ProxyFix配置正确(辅助项)
你之前的ProxyFix配置x_prefix=1是对的,但要确保它在Flask app初始化之后设置,比如:
from flask import Flask from werkzeug.middleware.proxy_fix import ProxyFix app = Flask(__name__) # 你的路由代码写在这里... app.wsgi_app = ProxyFix(app.wsgi_app, x_prefix=1)
如果前面的步骤解决了转发问题,这一步只是帮Flask更好识别代理前缀,核心问题还是在IIS/ARR的转发配置上。
测试验证
改完配置后,重启两个IIS站点(80端口的默认站点和Flask的8081站点),访问http://xpto/digitalquality/api/users,然后在Flask里加个日志打印请求路径:print(request.path),确认输出是不是/api/users。
内容的提问来源于stack exchange,提问作者Vitor

