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

Blazor Server SPA被SEO爬虫访问时返回Soft 404问题求助

问题描述

当SEO爬虫直接访问Blazor Server SPA的内部URL/页面时,会返回「Soft 404」错误;但通过浏览器访问同一URL时,能正常返回预期页面内容且无错误。需要解决此「Soft 404」问题,让SEO爬虫能获取与浏览器相同的页面内容。

我们使用Blazor Server技术(ASP.NET Core 6.0)开发该SPA并部署在AWS EC2上,这是一个公开站点,通过NavigationManager根据路由提供动态页面内容,已提交包含所有导航URL的sitemap.xml文件用于SEO优化。

更多细节

  • Blazor渲染模式:Server
  • SignalR版本:Microsoft.AspNetCore.SignalR.Client 6.0.0

请求URL的响应内容

An error has occurred. This application may no longer respond until reloaded. Reload 🗙
Attempting to reconnect to the server... Reload
Reconnection failed. Try Reload the page if you're unable to reconnect.
Couldn't connect to the server Reload


相关代码文件

_Host.cshtml

@page "/"
@namespace App.Pages
@addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers
@{
    Layout = "_Layout";
}

@*
    如果我们使用ServerPreRender渲染模式,CustomAuthenticationStateProvider在预渲染阶段访问本地存储时会抛出异常。
    注意:在Blazor Server的预渲染中,直到OnAfterRender生命周期方法才能执行任何JS互操作。
    *@
<component type="typeof(App)" render-mode="Server" />

_Layout.cshtml

<head>
    <base href="~/" />
    
    <component type="typeof(HeadOutlet)" render-mode="Server" />
</head> 
<body>
    @RenderBody()

    <div id="blazor-error-ui">
        <environment include="Staging,Production">
            发生错误。此应用可能需要重新加载才能继续响应。
        </environment>
        <environment include="Development">
            发生未处理的异常。请查看浏览器开发工具了解详情。
        </environment>
        <a href="" class="reload">重新加载</a>
        <a class="dismiss">🗙</a>
    </div>

    <environment include="Staging,Production,Development">
        <div id="components-reconnect-modal" class="my-reconnect-modal components-reconnect-hide">
            <div class="show">
                <p>
                    正在尝试重新连接服务器...
                    <a href="" target="_top">重新加载</a>
                </p>
            </div>
            <div class="failed">
                <p>
                    重新连接失败。如果无法重新连接,请尝试
                    <a href="" target="_top">重新加载</a>页面。
                </p>
            </div>
            <div class="rejected">
                <p>
                    无法连接到服务器
                    <a href="" target="_top">重新加载</a>
                </p>
            </div>
        </div>
    </environment>

    <script src="_framework/blazor.server.js"></script>
</body>
</html>

Program.cs

try
{
    var builder = WebApplication.CreateBuilder(args);

    // 向容器添加服务。
    builder.Services.AddRazorPages().AddNewtonsoftJson();
    builder.Services.AddControllers();
    builder.Services.AddServerSideBlazor().AddCircuitOptions(options =>
    {
        // 将详细错误设置为'true',以便在开发环境中在浏览器显示详细的未处理异常消息。
        options.DetailedErrors = true;
    });
    
    // 其他依赖的Scoped和Transient服务及模型
    
    builder.Services.AddSignalR();
    
    var app = builder.Build();

    // 配置HTTP请求管道。
    if (!app.Environment.IsDevelopment())
    {
        app.UseExceptionHandler("/Error");
    }

    app.UseHttpsRedirection();

    app.UseStaticFiles();

    app.UseRouting();
    app.UseAuthentication();
    app.UseAuthorization();

    app.UseEndpoints(endpoints =>
    {
        endpoints.MapControllers();
        endpoints.MapBlazorHub();
        app.MapHub<ChatHub>("/chathub");
        endpoints.MapFallbackToPage("/_Host");
    });

    app.Run();
}
catch (Exception ex)
{
    Log.Fatal(ex, "应用启动失败。");
}
finally
{
    //Log.CloseAndFlush()仅需在控制台应用中调用一次,在应用退出前执行。
    Log.CloseAndFlush();
}   

我的理解

爬虫直接访问页面时,Blazor组件和SignalR连接默认无法建立,需要实现让爬虫获取页面内容而非重连错误。


解决方案

1. 修复预渲染认证问题,启用ServerPrerendered模式

当前使用的Server渲染模式不会预渲染页面内容,爬虫因不执行JS、无法建立SignalR连接,只能看到错误提示。启用ServerPrerendered模式可让服务器先渲染完整页面内容返回给爬虫,后续浏览器再建立SignalR连接交互。

针对预渲染时CustomAuthenticationStateProvider访问本地存储报错的问题,修改认证状态提供程序逻辑:

  • 在OnInitializedAsync(预渲染阶段)跳过依赖本地存储的操作,此时JS互操作不可用;
  • 在OnAfterRenderAsync(JS可用阶段)再执行本地存储相关的认证逻辑。

修改_Host.cshtml中的渲染模式:

<component type="typeof(App)" render-mode="ServerPrerendered" />

2. 为爬虫请求返回静态化内容

如果预渲染仍有问题,可针对爬虫的User-Agent返回提前静态化的页面内容:

  • 在Program.cs中添加中间件识别爬虫User-Agent;
  • 匹配到爬虫时,返回对应URL的静态HTML文件(可通过定时任务或按需生成)。

示例中间件:

app.Use(async (context, next) =>
{
    var userAgent = context.Request.Headers.UserAgent.ToString();
    var crawlerAgents = new[] { "Googlebot", "Bingbot", "Slurp", "DuckDuckBot" };
    if (crawlerAgents.Any(agent => userAgent.Contains(agent, StringComparison.OrdinalIgnoreCase)))
    {
        var requestPath = context.Request.Path.HasValue ? context.Request.Path.Value.TrimStart('/') : "index";
        var staticFilePath = Path.Combine(app.Environment.WebRootPath, "static", $"{requestPath}.html");
        if (File.Exists(staticFilePath))
        {
            await context.Response.SendFileAsync(staticFilePath);
            return;
        }
    }
    await next();
});

3. 确保路由正确映射

确认MapFallbackToPage配置正确,所有Blazor路由都能回退到/_Host,同时排查是否有其他中间件拦截爬虫请求返回错误。

4. 完善SEO元数据配置

利用HeadOutlet组件确保每个页面的PageTitle、Meta标签在预渲染时正确生成,让爬虫能抓取到完整的SEO相关内容。


内容的提问来源于stack exchange,提问作者Ananth MK

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.24 22:27:31