在浏览器中安全预览 Base64 图片

先解码为字节,检查位图格式,管理 Blob URL,并区分 Base64 错误与图片加载错误。

可靠的图片预览包含两个独立步骤:解码 Base64,再解码图片格式。字符串可以通过第一步,却因为截断、类型错误或浏览器不支持而无法显示。界面应区分这些状态。

始终以字节为中间结果

通过解析器移除已识别的 Data URI,校验 Base64,然后得到 Uint8Array。不要让图像字节经过文本解码器。本地预览可以将字节封装为 Blob,再生成对象 URL,避免为了显示而重新构造很长的 Base64。

async function previewRaster(bytes, type, imageElement) {
  const allowed = ['image/png', 'image/jpeg', 'image/webp', 'image/gif'];
  if (!allowed.includes(type)) throw new Error('不支持的位图预览类型');
  const url = URL.createObjectURL(new Blob([bytes], { type }));
  try {
    imageElement.src = url;
    await imageElement.decode();
    return { width: imageElement.naturalWidth, height: imageElement.naturalHeight,
      dispose: () => URL.revokeObjectURL(url) };
  } catch (error) {
    URL.revokeObjectURL(url);
    imageElement.removeAttribute('src');
    throw error;
  }
}

及时释放对象 URL

替换或移除预览时调用返回的 dispose。反复预览却不清理会占用浏览器资源。不要在加载完成之前释放,也不要把已释放的 URL 用于后续下载。下载需要继续可用时,应单独管理生命周期。

使用真实图片解码反馈

文件头只是初步线索。图像元素的 decode 可以检查浏览器是否能加载,并获得尺寸。此处失败时,应说明图片解码失败,同时保留原始字节供检查或下载,而不是误报 Base64 字母表错误。

尽可能在昂贵渲染前限制字节和尺寸,小型压缩文件也可能展开为巨大图片。SVG 属于结构化标记,不能与普通位图一视同仁,更不能直接把未知 SVG 或 HTML 插入页面。

预览与转换也不同:显示 JPEG 不会产生 PNG。转换需要将解码图像绘制到画布,再按目标格式导出,并明确质量和透明度选择。Data URI 语法见 MDN: data URLs;预览成功只是浏览器格式检查,不是通用安全认证。