如何合并ASP.Net Core 7的两个RewriteOptions实现单次重定向?
在ASP.NET Core 7中合并HTTPS与非WWW强制跳转为单次重定向
默认的AddRedirectToHttpsPermanent和AddRedirectToNonWww是按顺序执行的规则,因此当请求同时为HTTP协议且带WWW前缀时,会先触发HTTPS跳转,再触发非WWW跳转,产生两次重定向。要实现单次跳转,你可以自定义重写逻辑,一次性完成协议转换和域名修正。
方法一:使用Lambda表达式自定义规则
这种方式灵活可控,能处理端口、路径、查询字符串等所有细节,直接在Program.cs中实现:
var builder = WebApplication.CreateBuilder(args); // 配置你的服务(如Mvc、Razor等) builder.Services.AddControllersWithViews(); var app = builder.Build(); // 配置自定义重写规则 var rewriteOptions = new RewriteOptions(); rewriteOptions.Add(context => { var request = context.HttpContext.Request; var host = request.Host; // 判断是否需要跳转:HTTP协议 或 主机名带WWW前缀 bool needRedirect = !request.IsHttps || host.Host.StartsWith("www.", StringComparison.OrdinalIgnoreCase); if (needRedirect) { // 生成去掉WWW前缀的主机名 string targetHost = host.Host.StartsWith("www.", StringComparison.OrdinalIgnoreCase) ? host.Host.Substring(4) : host.Host; // 构建最终的HTTPS URL,保留端口(如果是非标准443端口)、路径和查询字符串 var targetUri = new UriBuilder( scheme: "https", host: targetHost, port: host.Port.GetValueOrDefault(443), path: (request.PathBase + request.Path).ToString(), extraValue: request.QueryString.ToString() ); // 返回308永久重定向(保留请求方法,适合POST等非GET请求) context.HttpContext.Response.Redirect(targetUri.ToString(), permanent: true, preserveMethod: true); context.Result = RuleResult.EndResponse; } }); app.UseRewriter(rewriteOptions); // 其他中间件配置(如静态文件、路由、授权等) app.UseStaticFiles(); app.UseRouting(); app.UseAuthorization(); app.MapControllerRoute( name: "default", pattern: "{controller=Home}/{action=Index}/{id?}"); app.Run();
逻辑说明
- 一次性判断请求是否同时/单独存在HTTP协议或WWW前缀的问题
- 直接构造最终的
https://example.com/xxx格式URL,包含路径和查询参数 - 使用308状态码(永久重定向且保留请求方法),和你之前使用的
AddRedirectToNonWww(308)保持一致
方法二:使用正则表达式跳转规则
如果你偏好简洁的正则写法,可以用AddRedirect直接添加匹配规则:
var rewriteOptions = new RewriteOptions() // 匹配HTTP/HTTPS带WWW的请求,跳转至HTTPS非WWW .AddRedirect(@"^http(s)?://www\.(.*)$", "https://$2", 308) // 匹配HTTP不带WWW的请求,跳转至HTTPS .AddRedirect(@"^http://(?!www\.)(.*)$", "https://$1", 308);
注意事项
- 正则规则需要注意域名的边界匹配,避免误匹配包含
www的子域名(如wwwsub.example.com) - 这种方式默认不会保留非标准端口,如果你应用使用了非443的HTTPS端口,需要额外处理
通过以上两种方式,都能让http://www.example.com、http://example.com、https://www.example.com这三种请求直接单次重定向到https://example.com,避免多次跳转的问题。
内容的提问来源于stack exchange,提问作者QINGCHARLES
相关产品推荐
相关产品推荐

