如何把 XML 编码为 Base64
- 把 XML 文档粘贴到 输入 · 文本,或点击 示例 加载一个小文档。
- 把 字符集 设为 XML 声明中指定的编码。默认已选 UTF-8,适合大多数文档。
- 从 输出 · Base64 复制结果。用于 JSON 和 HTTP 字段时,换行 保持 不换行;有些基于 XML 的协议接受每行 76 字符的格式。
- 下载 会把 Base64 保存为
base64.txt。
示例是一个 XML 声明加一个 <note> 元素,编码后的字符串以 PD94bWwg 开头,也就是 <?xml 的 Base64。几乎所有带声明的 XML 文档都以此开头,所以编码后的 XML 很容易识别。Base64 转 XML 可以再把它解码回来。
字符集要与 XML 声明一致
XML 解析器根据声明中的 encoding 属性(或字节顺序标记)决定如何读取字节。如果字节与声明不一致,接收方读到的字符就会和你写的不同。
| 文档 | 这里使用的字符集 | Base64 | 解析器读到的 |
|---|---|---|---|
<?xml version="1.0" encoding="ISO-8859-1"?><n>café</n> | ISO-8859-1 | PD94bWwg...PjxuPmNhZuk8L24+ | café |
| 同一个文档 | UTF-8 | PD94bWwg...PjxuPmNhZsOpPC9uPg== | café |
第二行是一个经典的集成 bug:文本以 UTF-8 保存,声明的却仍是 Latin-1。要么在这里选择声明的字符集,要么(更好的做法)把声明改为 UTF-8,并且处处都用 UTF-8。
XML 以 Base64 形式出现在哪里
- SOAP 和 REST API,它们在 JSON 或 XML 字段中接收整个 XML 文档,这样尖括号和引号就不需要转义。电子发票和 EDI 服务常以这种方式接收发票(例如 UBL 文档)。
- SAML 单点登录。 SAML 响应是一个 XML 文档,经 Base64 编码后由浏览器提交。SAML 解码器 可以把
SAMLResponse和SAMLRequest值还原为 XML。 - 配置和密钥。 存放在环境变量或 Kubernetes Secret 中的 XML 配置文件会使用 Base64,以便放在一行里。
当文档带有数字签名时(XML-DSig,用于 SAML 和许多电子发票方案),请编码你收到或生成的确切字节。重新缩进、改变换行符或在编辑器中重新保存文件,即使 XML 的含义不变,也可能让签名失效。
大小和换行
Base64 会让文档增大约 33%。XML 本身就很冗长,所以大文档常常在编码前先做 gzip 压缩;gzip 和 Base64 工具 可以一次完成两步。基于 MIME 的传输以及大多数 XML Schema 校验器都接受 xs:base64Binary 内容按 76 字符 换行。基于 JSON 的 API 通常需要不间断的一整行。
在代码中把 XML 转为 Base64
以字节方式读取文件并编码这些字节,这样声明和字节就不会对不上:
import base64
with open("invoice.xml", "rb") as f:
b64 = base64.b64encode(f.read()).decode("ascii")
// Node.js
const fs = require("fs");
const b64 = fs.readFileSync("invoice.xml").toString("base64");
在 Linux 上,base64 -w 0 invoice.xml 会输出同样的单行结果。大文件的流式处理见 Python 中的 Base64 和 Node.js 中的 Base64。
常见问题
如何把 XML 文件转换为 Base64?
把 XML 粘贴到上面,复制结果即可。对于文件,请直接编码原始字节,而不是重新输入文本:在 Python 中用 base64.b64encode(open("doc.xml", "rb").read()),在 Linux 上用 base64 -w 0 doc.xml。
XML 应该选择哪个字符集?
选 XML 声明中的那个。<?xml version="1.0" encoding="UTF-8"?> 或没有 encoding 属性时,就是默认的 UTF-8。如果声明的是 ISO-8859-1 或 Windows-1252,就选它,或者把声明改为 UTF-8。
编码前能重新格式化 XML 吗?
只有在没有任何东西依赖确切字节时才可以。缩进会改变 Base64;对于签名的 XML(SAML 断言、签名发票),还可能让签名失效。
xs:base64Binary 又是怎么回事?
这个 XML Schema 类型是反过来的情况:XML 元素中的 Base64,用于在 SOAP 消息和发票中嵌入文件。用 文件转 Base64 编码文件,再把结果粘贴到元素中即可。