上传BunnyCDN时文件内容无效:Buffer转Octet Stream问题求助
解决BunnyCDN上传文件内容无效问题
问题背景
修改@dan-online/bunnycdnjs库实现文件上传到BunnyCDN,使用express-fileupload处理前端文件上传,但上传后文件内容无效(如图片文件变为base64文本内容)。
相关代码
修改的Upload方法
async Upload( path: string, filename: string, content: string | ReadStream ): Promise<APIResponse<any>> { let url = `${this.endpoint}/${this.storageZoneName}/${path}/${filename}`; return new Promise((resolve) => { let options: request.CoreOptions = { method: "PUT", headers: { AccessKey: this.apiKey, 'Content-Type': 'application/octet-stream', }, body: content, }; let handle: request.RequestCallback = (err, res, body) => { let HttpResponse = res; let _Error = err; let IsLocalError = false; let Data; try { let parsed = JSON.parse(body); Data = parsed; } catch (err) { _Error = err; IsLocalError = true; } resolve({ HttpResponse, Error: _Error, IsLocalError, Data, }); }; request(url, options, handle); }); }
BunnyCDN客户端配置
const BunnyClient = new Bunny({ apiKey: BUNNY_STORAGE_KEY, storageZoneName: BUNNY_STORAGE_ZONE, cdnLocation: 'Main' });
Express配置与上传路由
import fileUpload from 'express-fileupload'; app.use(express.json({limit: '500mb'})); app.use(express.urlencoded({limit: '500mb', extended: true})); app.use(fileUpload({ limits: { fileSize: 500 * 1024 * 1024 }, })); app.post('/api/_createEpisode', async (req, res) => { if (!req.files || ['video'].some(key => !req.files[key])) return res.json(APIResponses.ERROR( ErrorCodes.BadRequest, { 'files': 'Err' } )); const {name, data} = req.files.video; await BunnyClient.Upload('test', name, data.toString('base64')); })
问题原因
上传时将文件Buffer转成了base64字符串(data.toString('base64')),导致BunnyCDN存储的是base64文本内容,而非原始二进制文件,因此文件无法正常解析使用。
BunnyCDN上传文档(翻译)
BunnyCDN 文档 - 上传文件
上传文件接口
请求方法:PUT
接口路径:/{存储区名称}/{路径}/{文件名}请求头:
- AccessKey: 你的BunnyCDN API密钥
- Content-Type: 文件对应的MIME类型,或使用
application/octet-stream表示通用二进制流请求体:文件的原始二进制内容
修正方案
1. 扩展Upload方法的参数类型
支持直接传递Buffer类型(express-fileupload返回的文件数据是Buffer):
async Upload( path: string, filename: string, content: string | ReadStream | Buffer // 新增Buffer类型支持 ): Promise<APIResponse<any>> { let url = `${this.endpoint}/${this.storageZoneName}/${path}/${filename}`; return new Promise((resolve, reject) => { // 新增reject支持错误捕获 let options: request.CoreOptions = { method: "PUT", headers: { AccessKey: this.apiKey, 'Content-Type': 'application/octet-stream', }, body: content, }; let handle: request.RequestCallback = (err, res, body) => { if (err) { return reject(err); } let HttpResponse = res; let _Error = err; let IsLocalError = false; let Data; try { let parsed = JSON.parse(body); Data = parsed; } catch (err) { _Error = err; IsLocalError = true; } resolve({ HttpResponse, Error: _Error, IsLocalError, Data, }); }; request(url, options, handle); }); }
2. 修改Express路由中的上传调用
直接传递文件Buffer,移除base64转换:
app.post('/api/_createEpisode', async (req, res) => { if (!req.files || ['video'].some(key => !req.files[key])) return res.json(APIResponses.ERROR( ErrorCodes.BadRequest, { 'files': 'Err' } )); const {name, data} = req.files.video; try { await BunnyClient.Upload('test', name, data); // 直接传Buffer res.json(APIResponses.SUCCESS()); } catch (err) { res.json(APIResponses.ERROR(ErrorCodes.InternalServerError, {error: err.message})); } })
验证说明
修改后上传的文件会以原始二进制形式存储到BunnyCDN,下载后可正常打开使用。
内容的提问来源于stack exchange,提问作者Wraith
相关产品推荐
相关产品推荐

