如何在UWP WebView中读取Blob文件数据?
在UWP WebView中读取Web应用传递的Blob数据
嘿,这个问题我刚好处理过!因为UWP的WebView和宿主应用处于不同的沙箱环境,你没法直接从宿主端访问WebView内部的Blob资源,得通过Web端把Blob数据转换成宿主能接收的格式才行,具体实现步骤如下:
步骤1:在Web应用中添加读取Blob并返回Base64的函数
首先在你的JavaScript代码里定义一个异步函数,用来接收Blob URL并返回对应的Base64编码数据(去掉data:image/png;base64,这类前缀):
async function getBlobDataAsBase64(blobUrl) { return new Promise((resolve, reject) => { const xhr = new XMLHttpRequest(); xhr.open('GET', blobUrl, true); xhr.responseType = 'blob'; xhr.onload = function() { if (xhr.status === 200) { const reader = new FileReader(); reader.onloadend = function() { // 拆分出纯Base64部分 const base64 = reader.result.split(',')[1]; resolve(base64); }; reader.readAsDataURL(xhr.response); } else { reject(new Error(`加载Blob失败,状态码:${xhr.status}`)); } }; xhr.onerror = () => reject(new Error('网络请求失败')); xhr.send(); }); }
步骤2:在UWP宿主端处理ScriptNotify事件并获取数据
当Web应用通过window.external.notify(blobUrl)触发ScriptNotify事件后,宿主端调用WebView的InvokeScriptAsync方法执行上面定义的JavaScript函数,拿到Base64数据后再转换为字节数组:
private async void WebView_ScriptNotify(object sender, NotifyEventArgs e) { var webView = sender as WebView; if (webView == null) return; string blobUrl = e.Value; // 验证是否是WebView内部的Blob URL if (!blobUrl.StartsWith("blob:ms-appx-web://")) return; try { // 调用Web端的getBlobDataAsBase64函数,获取Base64数据 string base64Data = await webView.InvokeScriptAsync("eval", new[] { $"getBlobDataAsBase64('{blobUrl}')" }); // 将Base64转换为字节数组 byte[] imageBytes = Convert.FromBase64String(base64Data); // 这里可以根据需求处理字节数组,比如保存为文件、显示到Image控件等 // 示例:保存到本地应用文件夹 StorageFile imageFile = await ApplicationData.Current.LocalFolder .CreateFileAsync("generated_image.png", CreationCollisionOption.ReplaceExisting); await FileIO.WriteBytesAsync(imageFile, imageBytes); } catch (Exception ex) { // 处理异常,比如日志记录 Debug.WriteLine($"读取Blob数据失败:{ex.Message}"); } }
关键注意事项
- 配置ScriptNotify权限:确保WebView的
AllowedScriptNotifyUris包含你的Web应用的源,开发阶段可以临时设置为WebView.AnyScriptNotifyUri,发布时建议限定具体的URI以保证安全性:webView.AllowedScriptNotifyUris = WebView.AnyScriptNotifyUri; - 异步处理:因为Blob读取和跨进程通信都是异步操作,一定要用
async/await避免阻塞UI线程。 - 大文件优化:如果生成的图片非常大,Base64可能会带来性能开销,这时候可以考虑分块读取Blob并分批次传递,不过一般场景下Base64已经足够好用。
内容的提问来源于stack exchange,提问作者Kibernetik
相关产品推荐
相关产品推荐

