.NET Core 6 MVC在IIS与Cloudflare下的URL重写/路由问题
解决.NET Core 6 MVC部署在IIS+Cloudflare后的URL路径问题
问题背景
我们的.NET Core 6 MVC应用部署在IIS上,实际访问地址为www.ExampleHost.com/ExampleApp。通过Cloudflare将该地址映射到新域名www.Example-App.eu后,访问新域名时所有请求的URL都会带上/ExampleApp路径,导致视图返回、表单提交等功能异常。尝试过通过web.config配置URL重写规则,但POST请求仍无法正常执行;也试过路由配置,同样未成功,寻求可行解决方案。
现有尝试的web.config规则
<rewrite> <rules> <rule name="RemoveExampleApp"> <match url=".*ExampleApp/(.*)" /> <conditions> <add input="{REQUEST_METHOD}" matchType="Pattern" pattern="POST" ignoreCase="true" negate="true" /> </conditions> <action type="Redirect" url="{R:1}"/> </rule> <rule name="RemoveExampleAppPost"> <match url=".*ExampleApp/(.*)" /> <conditions> <add input="{REQUEST_METHOD}" matchType="Pattern" pattern="POST" ignoreCase="true" /> </conditions> <action type="Rewrite" url="{R:1}" /> </rule> </rules> </rewrite>
可行解决方案
方案一:修正IIS URL重写规则
原规则的匹配逻辑和请求处理拆分存在问题,调整后的规则可以同时处理GET和POST请求,并确保应用正确识别外部域名:
<rewrite> <rules> <!-- 移除URL中的ExampleApp前缀,统一处理所有请求方法 --> <rule name="RemoveExampleAppPrefix" stopProcessing="true"> <match url="^(ExampleApp)/(.*)" /> <action type="Rewrite" url="{R:2}" /> </rule> <!-- 设置反向代理头部,让应用生成正确的外部URL --> <rule name="SetForwardedHeaders" stopProcessing="true"> <match url=".*" /> <serverVariables> <set name="HTTP_X_FORWARDED_HOST" value="www.Example-App.eu" /> <set name="HTTP_X_FORWARDED_PROTO" value="https" /> </serverVariables> <action type="None" /> </rule> </rules> </rewrite>
说明:
- 第一条规则直接匹配以
ExampleApp/开头的路径,重写为去掉前缀的目标路径,无需拆分GET/POST处理。 - 第二条规则设置Cloudflare代理的转发头部,确保.NET Core应用生成的链接、表单提交地址等直接使用新域名,不带
/ExampleApp前缀。
方案二:配置.NET Core应用的转发头部与路由
仅靠IIS重写可能不足以解决视图URL生成问题,需要在应用代码中补充配置:
- 在
Program.cs中添加转发头部支持,处理Cloudflare的代理请求:
var builder = WebApplication.CreateBuilder(args); // 配置转发头部,识别Cloudflare的代理信息 builder.Services.Configure<ForwardedHeadersOptions>(options => { options.ForwardedHeaders = ForwardedHeaders.XForwardedFor | ForwardedHeaders.XForwardedProto; // 生产环境建议添加Cloudflare的具体IP段,这里示例使用官方公开的代理IP段 options.KnownProxies.Add(IPAddress.Parse("198.41.214.0/24")); options.KnownProxies.Add(IPAddress.Parse("198.41.215.0/24")); }); // 配置路由规则 builder.Services.AddRouting(options => { options.LowercaseUrls = true; }); // 添加MVC服务 builder.Services.AddControllersWithViews(); var app = builder.Build(); // 必须在路由中间件前启用转发头部 app.UseForwardedHeaders(); // 其他中间件配置(静态文件、错误页等) app.UseStaticFiles(); app.UseRouting(); app.UseAuthorization(); // 默认路由配置 app.MapControllerRoute( name: "default", pattern: "{controller=Home}/{action=Index}/{id?}"); app.Run();
- 可选:添加域名重定向中间件,强制所有请求使用新域名:
app.Use(async (context, next) => { if (!context.Request.Host.Host.Equals("www.Example-App.eu", StringComparison.OrdinalIgnoreCase)) { var redirectUrl = new UriBuilder(context.Request.Scheme, "www.Example-App.eu", context.Request.Host.Port, context.Request.Path, context.Request.QueryString.ToString()); context.Response.Redirect(redirectUrl.ToString(), permanent: true); return; } await next(); });
方案三:Cloudflare页面规则补充
在Cloudflare控制台添加页面规则,确保请求转发时隐藏原路径前缀:
- 规则URL:
www.Example-App.eu/* - 设置项:选择“转发URL”,目标地址填写
www.ExampleHost.com/ExampleApp/$1,转发类型选择“隐藏路径”(此设置会让用户浏览器地址栏始终显示新域名,不带/ExampleApp)
内容的提问来源于stack exchange,提问作者Michalis
相关产品推荐
相关产品推荐

