Base64编码PDF上传至Box API存为文本而非文件问题求助
问题分析与解决建议
核心问题出在发送的是Base64编码的字符串文本,而非解码后的二进制PDF数据,即使添加了Content-Transfer-Encoding: BASE64头,Box API也不会自动解码该内容,它期望直接接收原始二进制文件字节流。
具体问题点
- 请求体构造方式错误:你将所有内容(包括Base64字符串)拼接成UTF-8字符串发送,这会把Base64文本原样传递给API,而非转换为二进制。
- 多余的编码头:
Content-Transfer-Encoding: BASE64适用于邮件等传统场景,Box文件上传API不依赖这个头来解码内容,直接发送二进制即可。 - 不必要的字符集声明:
application/pdf是二进制类型,不需要添加charset=UTF-8,这可能干扰API对内容类型的识别。
解决步骤
1. 将Base64内容解码为二进制字节流
首先把testFile.getContents()返回的Base64字符串解码为原始二进制数据,在GraalVM环境中可使用atob(若环境支持)完成解码:
const base64Str = testFile.getContents(); // 解码Base64为二进制Uint8Array const binaryData = Uint8Array.from(atob(base64Str), char => char.charCodeAt(0));
2. 构造二进制格式的multipart请求体
不能用字符串拼接所有内容,需将文本部分(边界、请求头、属性JSON)转换为UTF-8字节,再与二进制文件数据拼接成完整的字节数组:
const boundary = 'ikjbhciuydgwyigdchbwikcbjlikwudhqcviudgwvcihblh'; const encoder = new TextEncoder(); // 构造属性部分的字节数组 const attributesPart = encoder.encode( `--${boundary}\r\n` + 'Content-Disposition: form-data; name="attributes"\r\n\r\n' + JSON.stringify({name: testFile.name, parent: { id: 12216548 }}) + '\r\n' ); // 构造文件部分的头字节数组 const fileHeaderPart = encoder.encode( `--${boundary}\r\n` + `Content-Disposition: form-data; name="file"; filename="${testFile.name}"\r\n` + 'Content-Type: application/pdf\r\n\r\n' ); // 构造结束边界的字节数组 const closingBoundary = encoder.encode(`\r\n--${boundary}--\r\n`); // 拼接所有字节数组 const bodyBytes = new Uint8Array([ ...attributesPart, ...fileHeaderPart, ...binaryData, ...closingBoundary ]);
3. 发送二进制请求体
调整https.post的body参数,传入二进制字节数组而非字符串:
const result = https.post({ url: 'https://upload.box.com/api/2.0/files/content', headers: { 'Content-Type': `multipart/form-data; boundary=${boundary}`, 'Authorization': 'Bearer XXXXXXXXXXXXXXXXXXXXXXXXXX' }, body: bodyBytes });
额外验证点
- 确认字段名
name="file"正确:Box API的文件上传字段名固定为file,需保持与API要求一致。 - 本地测试中Multer无法处理手动构造的Base64文本,而Formidable会自动解析multipart中的二进制内容,这和Box API的行为一致——它们都期望原始二进制而非Base64字符串。
内容的提问来源于stack exchange,提问作者Matthew Carter
相关产品推荐
相关产品推荐

