You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何合并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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.24 23:07:34