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

升级Blazor WebAssembly至.NET 7后index.html脚本加载失效

.NET 7 Blazor WASM动态注入JS脚本失效的原因与修复

失效原因

.NET 7对Blazor WASM的启动流程做了调整:Blazor.start()返回的Promise会在Blazor运行时初始化完成、但组件尚未开始渲染时就完成回调。而你通过动态创建script标签注入的MyJS.js是异步加载的,当Blazor组件尝试调用其中的函数时,脚本大概率还没加载完成,直接导致函数未定义的错误。

你提到的缓存问题不是本次失效的直接原因,但可以结合修复方案一并解决。

修复方案(保留动态注入方式)

方案1:先加载脚本,再启动Blazor

这是最稳妥的方式,确保Blazor组件渲染时,JS函数已经完全可用,同时添加缓存破击参数避免缓存:

<script src="_framework/blazor.webassembly.js"></script>
<script>
    function loadJSHelper() {
        return new Promise((resolve, reject) => {
            const JSHelperScript = document.createElement('script');
            // 添加时间戳作为版本参数,避免缓存
            JSHelperScript.src = '/_content/SampleApp/scripts/MyJS.js?v=' + Date.now();
            JSHelperScript.onload = resolve;
            JSHelperScript.onerror = () => reject(new Error('Failed to load MyJS.js'));
            document.head.appendChild(JSHelperScript);
        });
    }

    // 先完成脚本加载,再启动Blazor
    loadJSHelper()
        .then(() => Blazor.start())
        .catch(err => {
            console.error(err.message);
            // 脚本加载失败时仍启动Blazor,可根据业务需求调整
            Blazor.start();
        });
</script>

方案2:保留原启动时机,监听脚本加载状态

如果坚持要在Blazor.start().then()中注入脚本,需要在JS脚本和Blazor组件之间添加加载状态同步逻辑:

  1. 修改MyJS.js,加载完成后主动通知Blazor:
// MyJS.js
// 封装所有函数到全局对象
window.MyJS = {
    targetFunction: function() {
        // 你的函数逻辑
    }
};

// 通知Blazor脚本已加载完成
if (window.Blazor?.notifyJSLoaded) {
    window.Blazor.notifyJSLoaded();
}
  1. 在index.html中添加状态监听逻辑:
<script src="_framework/blazor.webassembly.js"></script>
<script>
    window.Blazor = window.Blazor || {};
    window.Blazor._jsLoaded = false;
    window.Blazor._jsLoadResolver = null;

    // 供Blazor调用的等待方法
    window.Blazor.waitForJS = () => {
        return new Promise(resolve => {
            if (window.Blazor._jsLoaded) {
                resolve(true);
            } else {
                window.Blazor._jsLoadResolver = resolve;
            }
        });
    };

    // 供JS脚本调用的通知方法
    window.Blazor.notifyJSLoaded = () => {
        window.Blazor._jsLoaded = true;
        window.Blazor._jsLoadResolver?.();
    };

    Blazor.start().then(() => {
        const JSHelperScript = document.createElement('script');
        JSHelperScript.src = '/_content/SampleApp/scripts/MyJS.js?v=' + Date.now();
        document.head.appendChild(JSHelperScript);
    });
</script>
  1. 在Blazor组件中等待脚本加载完成后再调用函数:
@inject IJSRuntime JS

protected override async Task OnInitializedAsync()
{
    // 等待JS脚本加载完成
    await JS.InvokeAsync<bool>("Blazor.waitForJS");
    // 调用MyJS中的函数
    await JS.InvokeVoidAsync("MyJS.targetFunction");
}

缓存优化补充

不管用哪种注入方式,给脚本URL添加动态版本参数都是避免缓存的可靠方式:

  • 用时间戳:?v=' + Date.now(),每次加载都生成新URL,适合开发环境
  • 用项目版本号:发布时替换为固定版本号(比如?v=1.0.0),适合生产环境,可通过Razor语法注入项目版本:
<script src="/_content/SampleApp/scripts/MyJS.js?v=@(typeof(Program).Assembly.GetName().Version)"></script>

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.13 02:30:50