如何以原始文件形式(非流/Buffer/base64)上传至Azure Blob存储
直接上传原始文件到Azure Blob Storage(无需base64/Buffer额外转换)
你完全不需要把文件转成base64来上传——Azure Storage SDK本身就支持直接上传原始文件流或File对象,这样既高效又能避免不必要的编码开销。我来帮你优化代码,实现直接上传原始文件的需求:
问题分析
你当前的代码把文件Buffer转成了base64字符串再上传,这其实是多此一举的操作。BlockBlobClient.upload()方法本身就支持直接接收Buffer、Readable Stream或者浏览器环境的File对象,直接上传原始数据会更高效。
另外,你的代码里还有一个小问题:main()是async函数,但你直接调用它却没有用await处理Promise,这可能会导致未捕获的错误,需要同步修正。
解决方案
场景1:Node.js环境上传本地文件
如果是在Node.js里上传本地的png/jpeg文件,你可以直接用文件流上传,不需要读成Buffer再转base64:
const { BlobServiceClient } = require("@azure/storage-blob"); const fs = require("fs"); const path = require("path"); const blobServiceClient = new BlobServiceClient( `https://${account}.blob.core.windows.net`, sharedKeyCredential, // 或者你的defaultAzureCredentials ); // 改进后的上传函数,支持直接上传本地文件路径 async function createBlobFromLocalFile(blobName, localFilePath) { try { const containerClient = blobServiceClient.getContainerClient('blue'); const blockBlobClient = containerClient.getBlockBlobClient(blobName); // 直接创建文件读取流上传 const fileStream = fs.createReadStream(localFilePath); const fileSize = fs.statSync(localFilePath).size; const uploadBlobResponse = await blockBlobClient.uploadStream( fileStream, undefined, // 使用默认块大小 undefined, // 使用默认并发数 { blobHTTPHeaders: { blobContentType: path.extname(localFilePath).slice(1) } } // 设置正确的MIME类型 ); console.log(`Upload block blob ${blobName} successfully`, uploadBlobResponse.requestId); return uploadBlobResponse.requestId; } catch (err) { console.error("Upload failed:", err); throw err; // 抛出错误让调用方统一处理 } } // 使用示例:上传本地的test.png createBlobFromLocalFile("test.png", "./test.png") .then(requestId => console.log("Request ID:", requestId)) .catch(err => console.error(err));
场景2:处理前端传来的File对象(比如Express上传)
如果你的代码是在后端接收前端上传的File对象(比如通过multer或者直接读取req.files),可以直接用File的Buffer或者stream上传:
// 假设你在Express中,用multer接收了上传的文件,req.file就是上传的File对象 async function createBlobFromUploadedFile(blobName, uploadedFile) { try { const containerClient = blobServiceClient.getContainerClient('blue'); const blockBlobClient = containerClient.getBlockBlobClient(blobName); // 直接上传文件的Buffer,无需转base64 const uploadBlobResponse = await blockBlobClient.upload( uploadedFile.buffer, uploadedFile.size, { blobHTTPHeaders: { blobContentType: uploadedFile.mimetype } } // 保留原始MIME类型 ); console.log(`Upload block blob ${blobName} successfully`, uploadBlobResponse.requestId); return uploadBlobResponse.requestId; } catch (err) { console.error("Upload failed:", err); throw err; } } // 使用示例(Express + multer) app.post('/upload', upload.single('image'), async (req, res) => { try { const requestId = await createBlobFromUploadedFile(req.file.originalname, req.file); res.status(200).json({ success: true, requestId }); } catch (err) { res.status(500).json({ success: false, error: err.message }); } });
关键要点
- 不要转base64:直接用原始的Buffer或Stream上传,减少内存占用和编码时间
- 设置正确的Content-Type:上传时指定
blobContentType,这样Blob存储的文件会保留正确的MIME类型,下载或访问时浏览器能正确识别 - 正确处理async/await:确保所有异步操作都用await,避免Promise未处理的问题
内容的提问来源于stack exchange,提问作者Amaan Imtiyaz
相关产品推荐
相关产品推荐

