.NET6从Blob URL下载PDF转Base64遇HttpClient不支持问题
问题描述
我有一个Blob格式的PDF文件URL,示例为blob:https://seller.walmart.com/51339eb8-5d7b-49a5-8f7b-258d88bc15f0,该URL仅能在生成它的计算机上访问。尝试用HttpClient下载该PDF并转换为Base64时,抛出以下异常:
System.NotSupportedException: The 'blob' scheme is not supported.
推测该PDF是在浏览器中生成的,但不清楚具体平台。以下是我尝试的代码:
static async Task<string> FetchPdfAndConvertToBase64(string pdfUrl) { using var httpClient = new HttpClient(); var response = await httpClient.GetAsync(pdfUrl); response.EnsureSuccessStatusCode(); byte[] blobBytes = await response.Content.ReadAsByteArrayAsync(); string base64string = Convert.ToBase64String(blobBytes); return base64string; }
原因分析
Blob URL是浏览器为内存中的Blob对象生成的临时本地URL,仅在当前浏览器会话内有效,并非指向服务器上的资源。HttpClient作为HTTP客户端,仅支持处理http/https协议的URL,自然不兼容blob协议,因此会抛出不支持的异常。
解决方案
根据运行环境,分两种场景处理:
1. 前端浏览器环境中处理
直接在浏览器内读取Blob内容并转换为Base64,无需通过HttpClient:
// 假设已获取Blob URL,直接转换为Base64 async function blobToBase64(blobUrl) { const blob = await fetch(blobUrl).then(res => res.blob()); return new Promise((resolve, reject) => { const reader = new FileReader(); reader.onloadend = () => resolve(reader.result.split(',')[1]); // 移除dataURL前缀 reader.onerror = reject; reader.readAsDataURL(blob); }); } // 使用示例 blobToBase64('blob:https://seller.walmart.com/xxx') .then(base64 => console.log(base64)) .catch(err => console.error(err));
2. 后端/桌面程序需要获取数据
如果必须在后端或桌面程序中处理,需要前端先将Blob数据传递过来:
- 前端可以将Blob转换为Base64后,通过API接口发送给后端;
- 或者将Blob作为FormData上传,后端接收字节流后再转换为Base64。
后端接收示例(C#)
如果前端上传的是文件:
[HttpPost("upload-pdf")] public async Task<IActionResult> UploadPdf(IFormFile file) { using var ms = new MemoryStream(); await file.CopyToAsync(ms); byte[] bytes = ms.ToArray(); string base64 = Convert.ToBase64String(bytes); // 后续处理base64 return Ok(base64); }
桌面程序(如WPF嵌入WebView2)场景
如果Blob是在程序内的WebView控件中生成的,可以通过WebView的API直接获取Blob数据:
// 基于WebView2控件获取Blob并转换为Base64 async Task<string> GetBlobFromWebView(WebView2 webView, string blobUrl) { string base64Result = await webView.ExecuteScriptAsync($@" (async function() {{ const blob = await fetch('{blobUrl}').then(res => res.blob()); return new Promise((resolve) => {{ const reader = new FileReader(); reader.onloadend = () => resolve(reader.result.split(',')[1]); reader.readAsDataURL(blob); }}); }})() "); // 去除脚本返回的引号 return base64Result.Trim('"'); }
内容的提问来源于stack exchange,提问作者aoiTenshi
相关产品推荐
相关产品推荐

