如何在新标签页展示Base64编码文件(含大体积PDF)?
如何在新标签页预览Base64编码的大文件(如6MB PDF)
问题场景
从服务器拿到Base64编码的文件数据(最大6MB的PDF),尝试用以下<a>标签直接预览时,URL会被浏览器截断:
<a href="data:image/png;base64,..." target="_blank">preview</a>
改用React/JS代码尝试打开时,仅把data URI文本打印在新页面,没有正确渲染文件:
const signatures = { JVBERi0: "application/pdf", R0lGODdh: "image/gif", R0lGODlh: "image/gif", iVBORw0KGgo: "image/png", "/9j/": "image/jpg" }; const detectMimeType= (b64) => { for (var s in signatures) { if (b64.indexOf(s) === 0) { return signatures[s]; } } return null; } const showPreview = (e,base64_data) => { e.preventDefault(); const mime_type = detectMimeType(base64_data); let data = "data:"+mime_type+";base64," + base64_data; var w = window.open(""); w.document.write(data); }
问题原因
- data URI长度限制:浏览器对URL长度有上限,大文件的Base64编码会超出限制导致截断
- 渲染方式错误:
document.write(data)会把完整的data URI当作纯文本输出,而非解析成对应的文件类型
解决方案:用Blob + URL.createObjectURL
这种方法不受data URI长度限制,适合大文件预览,步骤如下:
修改后的React/JS代码
const signatures = { JVBERi0: "application/pdf", R0lGODdh: "image/gif", R0lGODlh: "image/gif", iVBORw0KGgo: "image/png", "/9j/": "image/jpg" }; const detectMimeType = (b64) => { for (var s in signatures) { if (b64.indexOf(s) === 0) { return signatures[s]; } } return null; }; // 把Base64转成Blob对象 const base64ToBlob = (base64Data, mimeType) => { const byteCharacters = atob(base64Data); const byteArrays = []; for (let offset = 0; offset < byteCharacters.length; offset += 512) { const slice = byteCharacters.slice(offset, offset + 512); const byteNumbers = new Array(slice.length); for (let i = 0; i < slice.length; i++) { byteNumbers[i] = slice.charCodeAt(i); } const byteArray = new Uint8Array(byteNumbers); byteArrays.push(byteArray); } return new Blob(byteArrays, { type: mimeType }); }; const showPreview = (e, base64_data) => { e.preventDefault(); const mime_type = detectMimeType(base64_data); if (!mime_type) return; // 转成Blob const blob = base64ToBlob(base64_data, mime_type); // 创建临时URL const blobUrl = URL.createObjectURL(blob); // 打开新标签页并加载Blob URL const newTab = window.open(); newTab.location.href = blobUrl; // 可选:页面加载完成后释放URL,避免内存泄漏 newTab.onload = () => { URL.revokeObjectURL(blobUrl); }; };
代码说明
- base64ToBlob函数:将Base64字符串解码为二进制数据,生成对应MIME类型的Blob对象
- URL.createObjectURL:为Blob生成临时的本地URL,这个URL没有长度限制
- 释放URL:在新标签页加载完成后调用
URL.revokeObjectURL,释放浏览器内存 - 兼容性:主流浏览器(Chrome、Firefox、Edge)都支持Blob和createObjectAPI,无需额外兼容处理
内容的提问来源于stack exchange,提问作者B L Praveen
相关产品推荐
相关产品推荐

