如何在Blazor Server应用的JavaScript函数中使用选中的文件?
Blazor Server 大文件本地JS分析(避免上传)
核心思路
直接在浏览器端通过原生HTML获取File对象,用Mediainfo.js本地分析,仅将分析结果(而非原文件)传给Blazor Server的C#代码,彻底规避大文件上传。
实现步骤
1. Razor组件中使用原生文件选择器
放弃Blazor自带的InputFile组件(会自动上传文件到服务器),改用原生<input type="file">:
<!-- 隐藏原生input,用按钮触发选择 --> <input type="file" id="localFileInput" @onchange="TriggerFileAnalysis" style="display: none;" /> <button @onclick="() => document.getElementById('localFileInput').click()">选择本地文件</button> <div> <h3>分析结果</h3> <pre>@analysisResult</pre> </div> @code { [Inject] private IJSRuntime JS { get; set; } private string analysisResult { get; set; } = "等待选择文件..."; private async Task TriggerFileAnalysis() { // 调用JS侧的分析函数,获取结果 analysisResult = await JS.InvokeAsync<string>("analyzeFileWithMediaInfo"); } }
2. 编写JS侧分析逻辑
在wwwroot/js/site.js中实现基于Mediainfo.js的文件分析,确保全程在浏览器本地处理:
// 确保已在index.html中引入Mediainfo.js(本地文件,无需外链) // <script src="js/mediainfo.min.js"></script> const fileInput = document.getElementById('localFileInput'); async function analyzeFileWithMediaInfo() { if (!fileInput.files || fileInput.files.length === 0) { return "未选择任何文件"; } const targetFile = fileInput.files[0]; // 初始化Mediainfo,指定输出格式为JSON const mediaInfo = await new MediaInfo({ format: 'JSON' }); try { // 流式读取文件分析,避免加载整个大文件到内存 const analysisResult = await mediaInfo.analyzeData( () => targetFile.size, // 返回文件总大小 (chunkSize, offset) => new Promise((resolve) => { const reader = new FileReader(); reader.onload = (e) => resolve(new Uint8Array(e.target.result)); // 读取指定偏移量的文件块 reader.readAsArrayBuffer(targetFile.slice(offset, offset + chunkSize)); }) ); return JSON.stringify(analysisResult, null, 2); } catch (error) { return `分析失败:${error.message}`; } finally { mediaInfo.close(); } }
关键说明
- 为什么不用
InputFile?Blazor Server的InputFile组件会将用户选择的文件上传到服务器,生成IBrowserFile对象,这必然导致大文件上传的开销,完全违背需求。 - Mediainfo.js的流式分析:
analyzeData方法通过分块读取文件,即使是GB级大文件也不会占用过多浏览器内存。 - 数据传输:仅将分析后的JSON结果(体积远小于原文件)通过JS互调传给C#,避免了大文件的网络传输。
内容的提问来源于stack exchange,提问作者AKuhlmann
相关产品推荐
相关产品推荐

