Blazor中JS生成PDF的base64值传递到C#的异步时序问题
解决方案
问题根因
你当前的问题本质是异步操作时序错误,html2pdf.output("datauristring")返回的是Promise对象,回调函数里的localStorage.setItem会在JS主线程同步任务执行完成后才触发,你后续的localStorage.getItem和return逻辑是同步执行的,此时本次PDF还未生成完成,读取到的永远是上一次存在本地存储的旧值。同时使用localStorage中转PDF完全冗余,还存在5M存储上限、旧值污染的问题。
修正方案
1. 重构JS异步函数,移除localStorage中转
async function getPDFFile() { const element = document.getElementById("report"); // 等待PDF异步生成完成 const pdfUri = await html2pdf().set({ html2canvas: { onclone: (element) => { const svgElements = Array.from(element.querySelectorAll('svg')); svgElements.forEach(s => { const bBox = s.getBBox(); s.setAttribute("x", bBox.x); s.setAttribute("width", bBox.width); s.setAttribute("height", s.scrollHeight); }); } }, scale: 4, jsPDF: { format: 'a3' } }).from(element).toPdf().output("datauristring"); // 直接处理后返回结果 return pdfUri.replace('data:application/pdf;base64,', ''); }
2. Blazor C#端适配异步JS调用
Blazor原生支持调用返回Promise的异步JS函数,直接用InvokeAsync方法即可:
// 注入JS运行时 [Inject] private IJSRuntime JSRuntime { get; set; } // 异步调用JS方法获取PDF base64 private async Task<string> GetPdfBase64Async() { // 不要用.Result/.Wait()做同步阻塞,避免死锁 return await JSRuntime.InvokeAsync<string>("getPDFFile", CancellationToken.None); }
在业务逻辑中直接异步调用GetPdfBase64Async()即可获取到本次生成的最新PDF base64值。
内容的提问来源于stack exchange,提问作者this.Amit
相关产品推荐
相关产品推荐

