Firefox调用IAsyncEnumerable Core MVC控制器方法触发WebSocket错误
问题背景
我使用可取消的JavaScript Fetch API,获取C# Microsoft.AspNet.WebApi.Core中IAsyncEnumerable类型的控制器方法返回的流式数据。在Chrome和Edge中运行完全正常,但Firefox会输出多条错误日志。我不清楚HTTP Fetch转WebSocket流式传输是否属于W3C标准,也不了解Microsoft是如何嵌入Browser-Link的,当前使用的是纯.html文件,而非.cshtml或Razor页面。
相关JS代码
<script type="application/javascript"> async function doit() { const decoder = new TextDecoder(); const abortControl = new AbortController(); const signal = abortControl.signal; setTimeout(() => { abortControl.abort(); console.log("*ABORTED*") }, 2000); // 模拟2秒后取消请求 const fetchOpts = {signal:signal, method:'GET', cache:"no-cache"}; const response = await fetch("https://localhost:7196/data/yieldfamilyname?inname=made", fetchOpts); const reader = response.body.getReader(); let result = await reader.read(); while (!result.done && !signal.aborted) { var personText = decoder.decode(result.value).replace(/\[|]/g, '').replace(/^,/, ''); var person = JSON.parse(personText); console.log("chunk is", person.familyName); try { result = await reader.read(); } catch (err) { console.log(err.message); break; } } reader.releaseLock(); } doit() </script>
日志信息
首次Yield数据后,Firefox控制台输出如下日志:
chunk is MADE fred.html:32:14 Use of Mutation Events is deprecated. Use MutationObserver instead. browserLink:3299:5701 Tools extension connected browserLink:50:1248 Initializing tools services... browserLink:50:1248 Initializing tools design surface service browserLink:50:1248 Initializing tools selection service browserLink:50:1248 Initializing tools tag navigation service browserLink:50:1248 Initializing tools hotkey manager service browserLink:50:1248 Host extension connected browserLink:50:1248 Initializing host services... browserLink:50:1248 chunk is MADEBGWE fred.html:32:14 Firefox can’t establish a connection to the server at wss://localhost:44312/ChunkIt/. aspnetcore-browser-refresh.js:234:24 WebSocket failed to connect. aspnetcore-browser-refresh.js:18:15 chunk is . . . . *ABORTED* fred.html:19:14 The operation was aborted. fred.html:38:15
现象解释
1. Browser-Link相关日志
这些日志来自ASP.NET的Browser-Link工具,它是Visual Studio提供的用于实时页面刷新、远程调试的功能。即使你用的是纯HTML文件,只要项目启用了Browser-Link,它就会自动向页面注入browserLink相关脚本。日志里的“Mutation Events弃用”提示,是这个注入脚本使用了已被W3C标记为弃用的API,和你的Fetch流式请求逻辑完全无关。
2. WebSocket连接失败日志
这个错误来自ASP.NET Core的aspnetcore-browser-refresh.js脚本,属于开发环境的热重载功能。热重载服务会尝试通过WebSocket和浏览器建立连接,实现代码修改后的页面自动刷新。但因为你使用的是纯HTML文件,热重载服务的配置可能不匹配,导致Firefox中WebSocket连接失败。同样,这个错误不影响你的Fetch流式数据获取逻辑。
3. Fetch取消时的“The operation was aborted”
这是正常预期行为:你通过AbortController主动取消了Fetch请求,Firefox会抛出这个错误,而你的代码已经通过try-catch捕获并处理了它,无需额外担心。
4. Fetch与WebSocket的关系
W3C的Fetch标准本身基于HTTP/1.1或HTTP/2的分块传输编码(Chunked Transfer Encoding)实现流式数据传输,没有规定要转换为WebSocket。你代码中获取的是ASP.NET IAsyncEnumerable返回的HTTP流式响应,和WebSocket完全无关。那些WebSocket相关日志都是开发工具的额外行为,和你的业务流式请求没有关联。
内容的提问来源于stack exchange,提问作者McMurphy

