Blazor无法识别独立JS文件中函数的问题求助
问题:Blazor JS互操作无法找到外部JS文件中的函数
创建了新的.js文件并关联到App.razor,但调用其中的getMessage函数时触发Microsoft.JSInterop.JSException,提示该函数未定义。但将函数直接写在App.razor的<script>标签内可正常运行。
错误日志
[2024-08-19T16:59:42.406Z] Error: Microsoft.JSInterop.JSException: Could not find 'getMessage' ('getMessage' was undefined). Error: Could not find 'getMessage' ('getMessage' was undefined). at https://localhost:7151/_framework/blazor.web.js:1:734 at Array.forEach (<anonymous>) at l.findFunction (https://localhost:7151/_framework/blazor.web.js:1:702) at b (https://localhost:7151/_framework/blazor.web.js:1:5445) at https://localhost:7151/_framework/blazor.web.js:1:3238 at new Promise (<anonymous>) at y.beginInvokeJSFromDotNet (https://localhost:7151/_framework/blazor.web.js:1:3201) at gn._invokeClientMethod (https://localhost:7151/_framework/blazor.web.js:1:62841) at gn._processIncomingData (https://localhost:7151/_framework/blazor.web.js:1:60316) at connection.onreceive (https://localhost:7151/_framework/blazor.web.js:1:53957) at Microsoft.JSInterop.JSRuntime.InvokeAsync[TValue](Int64 targetInstanceId, String identifier, Object[] args) at BlazorApplication.Server.Components.ThemeButton.ChangeTheme() at Microsoft.AspNetCore.Components.ComponentBase.CallStateHasChangedOnAsyncCompletion(Task task) at Microsoft.AspNetCore.Components.RenderTree.Renderer.GetErrorHandledTask(Task taskToHandle, ComponentState owningComponentState)
相关代码示例
App.razor代码
<body> <Routes @rendermode="InteractiveServer" /> <script> window.getMessage = () => { return "Hello, World!"; }; </script> <!-- 可正常运行 --> <script src="~/js/custom.js"></script> <!-- 无法运行,但包含相同函数 --> <script src="~/js/bootstrap.bundle.min.js"></script> <script src="_framework/blazor.web.js"></script> </body>
JS互操作组件代码
@inject IJSRuntime JS <button class="btn btn-outline-primary" @onclick="ChangeTheme">Change theme</button> <br /> <span>Message: @Text</span> @code { private string Text = ""; private async Task ChangeTheme() { Text = await JS.InvokeAsync<string>("window.getMessage"); } }
解决方案
1. 确认JS文件路径与内容正确性
- 确保
custom.js存放在项目的wwwroot/js目录下(Blazor静态资源默认从wwwroot加载),路径改用绝对路径/js/custom.js避免解析问题。 - 检查
custom.js内的函数是否正确挂载到全局window对象,不能写成局部函数:window.getMessage = () => { return "Hello, World!"; };
2. 验证脚本是否成功加载
打开浏览器开发者工具的Network标签,查看custom.js的请求状态:
- 如果返回404,说明路径配置错误,需修正文件存放位置或引用路径。
- 如果返回200但仍报错,检查文件内容是否与内嵌脚本完全一致。
3. 调整脚本加载时机
在InteractiveServer模式下,可将自定义脚本放在<head>标签内并添加defer属性,确保DOM加载完成后脚本才执行:
<head> <!-- 其他头部内容 --> <script src="/js/custom.js" defer></script> </head>
4. 使用ES模块(推荐)
避免全局对象污染,将custom.js改为ES模块,通过模块导入方式调用:
custom.js内容:export function getMessage() { return "Hello, World!"; }- 组件代码修改:
@inject IJSRuntime JS @implements IDisposable <button class="btn btn-outline-primary" @onclick="ChangeTheme">Change theme</button> <br /> <span>Message: @Text</span> @code { private string Text = ""; private IJSObjectReference? _jsModule; protected override async Task OnAfterRenderAsync(bool firstRender) { if (firstRender) { _jsModule = await JS.InvokeAsync<IJSObjectReference>("import", "/js/custom.js"); } } private async Task ChangeTheme() { if (_jsModule != null) { Text = await _jsModule.InvokeAsync<string>("getMessage"); } } public void Dispose() { _jsModule?.DisposeAsync(); } }
内容的提问来源于stack exchange,提问作者Esper
相关产品推荐
相关产品推荐

