☰
Node.js 实战:读取图片并转换为 Base64 DataURI 嵌入 HTML(nodejs-learning-guide)
2026/10/7 2:00:34 网站建设 项目流程
  • 文档
  • 教程
  • 后端

【免费下载链接】nodejs-learning-guide

Nodejs学习笔记以及经验总结,公众号"程序猿小卡"

项目地址:https://gitcode.com/gh_mirrors/no/nodejs-learning-guide
点击查看免费下载

本文围绕 GitHub 加速计划 / no 项目 nodejs-learning-guide 中《将图片转成 datauri 嵌入 html》一文的完整主题展开:介绍如何用 Node.js 将本地图片文件读取为二进制数据,再编码为 Base64 字符串,最终拼接成可直接嵌入网页<img>标签的 Data URI。读完本文,你将掌握fs.readFileSync+Buffer.toString('base64')这一最小实现链路,并能把它扩展成一段可直接运行的 HTTP 服务,将图片以 DataURI 形式内联到 HTML 页面中,适合用于富文本、邮件正文、离线页面等不便外链图片资源的场景。

问题来源:如何把图片“嵌进”网页

本主题最初源于一次开发者社区的真实提问(见 assets/base64.png):在 QQ 群里有人问到“nodejs 读取图片,转成 base64,怎么读取呢?”。这个问题的本质,并不是单纯想知道“如何输出一段 Base64 字符串”,而是希望把图片以数据形式内嵌到网页中去——也就是把图片转换成对应的 Data URI(datauri)。

这种做法的典型价值在于:图片不再依赖独立的 URL 请求,而是直接随 HTML 一并传输,从而减少 HTTP 请求数、便于离线查看或嵌入富文本内容。原文档作者快速实现了一个简单 demo 并记录在仓库中,对应示例位于 examples/2016.11.15-base64-datauri。

实现思路:三步走

整个转换思路非常直观,只有三个步骤:

  1. 读取图片二进制数据—— 用fs.readFileSync得到图片文件的二进制内容(在 Node.js 中表现为Buffer对象);
  2. 转成 Base64 字符串—— 通过Buffer.toString('base64')将二进制字节编码为 Base64 文本;
  3. 拼成 Data URI—— 按 Data URI 的规范格式拼接出最终字符串。

关于 Base64 编码本身:它是一套用 64 个可打印字符(A-Z、a-z、0-9、+、/,以及末尾可能出现的=填充符)来表示任意二进制数据的编码方案,常用于在文本协议中安全地传输二进制内容。

而Data URI 的标准格式如下:

data:[<mediatype>][;base64],<data>

其中各段含义为:

片段含义
data:固定协议前缀,标识这是一个数据 URI
[<mediatype>]媒体类型(MIME type),如image/png、image/jpeg、text/plain,可省略
[;base64]可选标记,表示<data>部分是 Base64 编码的二进制数据
,<data>逗号分隔符之后即实际数据(Base64 字符串或文本内容)

具体到一张 PNG 图片,拼出来的 Data URI 大致如下,其中xxx就是前面得到的 Base64 字符串:

data:image/png;base64, xxx

最小实现:三步代码全解析

下面按原文档的步骤,逐一给出可运行的代码。

第一步:读取本地图片的二进制数据

var fs = require('fs'); var filepath = './1.png'; var bData = fs.readFileSync(filepath);

fs.readFileSync以同步方式读取文件,返回的是Buffer对象,即图片文件的原始字节序列。注意这里不要传入encoding参数,否则读取结果会直接变成字符串,也就丢失了后续按 Base64 编码的基础。

第二步:把二进制数据转换成 Base64 字符串

var base64Str = bData.toString('base64');

Buffer.toString([encoding[, start[, end]]])负责把 Buffer 解码成字符串,encoding决定解码方式,常见取值有utf8、ascii、base64、hex等,默认是utf8。这里显式传入'base64',即把二进制字节按 Base64 规则编码成字符串。关于Buffer.toString的更多用法,可以参考仓库内 模块/buffer.md(如buf.toString('utf8', 0, 2)这种带起始位置的切片解码示例)。

第三步:拼接成 Data URI

var datauri = 'data:image/png;base64,' + base64Str;

把 Data URI 固定前缀、图片的 MIME 类型与 Base64 字符串拼接即可。如果图片是 JPEG,前缀则相应换成data:image/jpeg;base64,。

完整示例(与仓库 examples/2016.11.15-base64-datauri/base64.js 中的实现完全一致,代码非常精简):

var fs = require('fs'); var filepath = './1.png'; var bData = fs.readFileSync(filepath); var base64Str = bData.toString('base64'); var datauri = 'data:image/png;base64,' + base64Str; console.log(datauri);

运行后会直接在终端输出一长串data:image/png;base64,....字符串。

实战扩展:把 DataURI 嵌入 HTML 并启动 HTTP 服务

仅仅打印出字符串还不够直观,仓库中的 examples/2016.11.15-base64-datauri/server.js 给出了一个更完整的实战版本:它用http模块起了一个监听 3000 端口的服务,把图片转成的 DataURI 直接替换进 HTML 模板的<img>标签中返回给浏览器。

var fs = require('fs'); var http = require('http'); var tmpl = '<!DOCTYPE html>\ <html>\ <head>\ <title>datauri例子</title>\ </head>\ <body>\ <img src="$datauri" />\ </body>\ </html>'; var server = http.createServer(function(req, res){ var filepath = './1.png'; var bData = fs.readFileSync(filepath); var base64Str = bData.toString('base64'); var datauri = 'data:image/png;base64,' + base64Str; res.end( tmpl.replace('$datauri', datauri) ); }); server.listen(3000);

这个版本把“读取 → 编码 → 拼接”三步骤封装在请求回调里,并用tmpl.replace('$datauri', datauri)把模板中的占位符替换成真实的 DataURI。浏览器解析<img src="data:image/png;base64,...">时,会直接解码 Base64 数据显示图片,不再发起额外的图片请求。

运行与验证

在仓库内进入对应示例目录并启动服务:

cd examples/2016.11.15-base64-datauri node server.js

然后在浏览器访问 http://127.0.0.1:3000,即可看到页面中渲染出内嵌的图片。示例目录中的 1.png 就是被转换的源图片。

如果你希望从仓库整体克隆后自行实验,也可以执行:

git clone https://gitcode.com/gh_mirrors/no/nodejs-learning-guide.git cd nodejs-learning-guide/examples/2016.11.15-base64-datauri node server.js

原理补充:为什么toString('base64')能完成转换

从源码层面看,这背后依赖的是 Node.js 的Buffer机制。fs.readFileSync(filepath)不带编码参数时返回Buffer,它是一段与图片文件字节一一对应的内存二进制数据;随后Buffer.toString('base64')把每个 3 字节的二进制分组映射为 4 个 Base64 字符(不足 3 字节时补=),从而得到可安全嵌入文本协议的 Base64 字符串。仓库 模块/buffer.md 中系统整理了 Buffer 的创建、转字符串、切片解码等用法,例如Buffer.from(string[, encoding])创建 Buffer 时若编码不一致会出现乱码,反过来也说明编码与解码必须一一对应——这也是此处必须显式传入'base64'而非使用默认utf8的原因:对图片这种非文本二进制,按utf8解码会产生乱码,而按base64解码则能完整还原二进制语义。

使用建议与注意事项

  • MIME 类型要匹配:Data URI 前缀中的image/png、image/jpeg等必须与图片实际格式一致,否则部分浏览器可能无法正确渲染。
  • 体积膨胀:Base64 编码会使数据体积比原始二进制增大约 1/3,data:前缀本身也有开销。小图标、缩略图适合内联,超大图片建议仍走独立静态资源路径。
  • 适合内联的场景:离线 HTML、邮件正文、富文本快照、减少小图片的请求数等;需要反复动态生成时,可以只做一次转换后缓存 DataURI 字符串。
  • 同步与异步取舍:示例中为演示简洁使用了fs.readFileSync,生产环境对高频请求建议改用fs.readFile异步版本,避免阻塞事件循环。

小结

本主题的核心链路极短:fs.readFileSync拿到二进制 Buffer →toString('base64')编码 → 拼接data:image/png;base64,前缀。配合仓库中 base64.js 与 server.js 两个可直接运行的示例,你可以快速把任意图片内联进网页。想深入了解 Buffer 解码规则,可继续阅读仓库内的 模块/buffer.md 与 2016.12.27-buffer 示例集。

  • 文档
  • 教程
  • 后端

【免费下载链接】nodejs-learning-guide

Nodejs学习笔记以及经验总结,公众号"程序猿小卡"

项目地址:https://gitcode.com/gh_mirrors/no/nodejs-learning-guide
点击查看免费下载
上一篇:掌握Ghost主题维护:Casper与Source主题的7个实用技巧
下一篇:打造专业视频编辑App时间线:基于android-advancedrecyclerview的终极拖拽实现指南

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询