如何使用Microsoft WebView2将动态加载的PDF保存到本地文件
解决方案:通过execScriptAsync获取WebView2中的PDF并保存
核心思路
你的页面里<embed>标签初始src是about:blank,说明PDF大概率是后续通过JavaScript动态加载的(比如Blob URL、Data URI或者PDF.js渲染)。这种情况下,可以用ExecuteScriptAsync执行前端脚本获取PDF数据,再传递到宿主程序保存到本地。
具体步骤
1. 执行脚本获取PDF数据源
先确认<embed>标签实际加载的PDF地址或数据,执行以下脚本即可:
// 获取页面中的PDF embed元素 const embed = document.querySelector('embed[type="application/pdf"]'); if (embed) { // 若为Blob URL,直接获取Blob内容并转为Base64传递给宿主 if (embed.src.startsWith('blob:')) { fetch(embed.src) .then(res => res.blob()) .then(blob => { const reader = new FileReader(); reader.onloadend = () => { // 通过WebView2的消息机制传递数据 window.chrome.webview.postMessage(reader.result); }; reader.readAsDataURL(blob); }); } else { // 若为普通URL,直接返回地址(需注意跨域限制) window.chrome.webview.postMessage(embed.src); } }
2. 宿主程序接收数据并保存(以C#为例)
先注册WebView2的消息接收事件,再执行脚本,最后处理数据保存:
// 注册消息接收回调 webView.CoreWebView2.WebMessageReceived += CoreWebView2_WebMessageReceived; // 执行前端脚本 await webView.CoreWebView2.ExecuteScriptAsync(@" const embed = document.querySelector('embed[type=""application/pdf""]'); if (embed) { if (embed.src.startsWith('blob:')) { fetch(embed.src) .then(res => res.blob()) .then(blob => { const reader = new FileReader(); reader.onloadend = () => { window.chrome.webview.postMessage(reader.result); }; reader.readAsDataURL(blob); }); } else { window.chrome.webview.postMessage(embed.src); } } "); // 处理接收到的PDF数据 private void CoreWebView2_WebMessageReceived(object sender, CoreWebView2WebMessageReceivedEventArgs e) { string receivedData = e.WebMessageAsString; if (receivedData.StartsWith("data:application/pdf;base64,")) { // 移除Base64前缀并转为字节数组 string pdfBase64 = receivedData.Replace("data:application/pdf;base64,", ""); byte[] pdfBytes = Convert.FromBase64String(pdfBase64); // 保存到本地文件 File.WriteAllBytes(@"C:\your\save\path\file.pdf", pdfBytes); } else { // 若收到的是普通URL,可根据需求进一步处理(但你提到WebClient受限,此分支可能暂用不上) Console.WriteLine($"PDF URL: {receivedData}"); } }
3. 关键注意事项
- 执行时机:必须确保PDF加载完成后再执行脚本,可通过监听WebView2的
NavigationCompleted事件,或前端监听<embed>的load事件后再触发数据传递。 - 跨域限制:如果Blob URL来自跨域资源,
fetch可能失败,需检查WebView2的跨域配置,或通过前端其他方式获取渲染后的PDF数据。 - PDF.js场景:若页面用PDF.js渲染PDF,需直接从PDF.js的文档实例中提取数据,而非从
<embed>标签获取。
内容的提问来源于stack exchange,提问作者Gabriel-Joy
相关产品推荐
相关产品推荐

