Node.js SDK v10及React应用中Azure Blob存储文件上传问题咨询
我来一步步帮你解决这两个Azure Blob存储的上传问题,附上具体的代码示例,应该能帮你顺利推进:
问题1:Node.js SDK v10中使用SAS Query参数上传文件到Azure Blob容器
首先确保你已经安装了正确版本的SDK包:
npm install @azure/storage-blob@10
假设你已经通过后端或其他方式获取到了sasQueryParameter对象,核心思路是把这些参数转换成URL查询字符串,拼接成带SAS授权的容器URL,然后使用ContainerClient来完成上传:
const { ContainerClient } = require("@azure/storage-blob"); // 替换成你实际获取到的SAS Query参数对象 const sasQueryParameters = { version: "2023-11-03", signature: "your-actual-sas-signature", se: "2024-06-01T23:59:59Z", sp: "rwl", // 确保包含写权限 spr: "https", sr: "c", sv: "2023-11-03" }; // 将SAS参数转换为URL查询字符串 const sasToken = new URLSearchParams(sasQueryParameters).toString(); // 替换成你的存储账户名和容器名 const containerBaseUrl = "https://your-storage-account.blob.core.windows.net/your-container"; const containerUrl = `${containerBaseUrl}?${sasToken}`; // 创建ContainerClient实例 const containerClient = new ContainerClient(containerUrl); // 上传本地文件的异步函数 async function uploadFileWithSAS() { try { const blobName = "your-file-name.txt"; // 上传后的Blob名称 const localFilePath = "./local/path/to/your/file.txt"; // 本地文件路径 // 获取BlockBlobClient并上传文件 const blockBlobClient = containerClient.getBlockBlobClient(blobName); const uploadResult = await blockBlobClient.uploadFile(localFilePath); console.log(`文件上传成功,ETag: ${uploadResult.etag}`); } catch (error) { console.error("上传失败:", error.message); } } // 执行上传 uploadFileWithSAS();
关键注意点:
- 确保SAS参数包含写权限(
sp字段包含w),否则会上传失败 - 如果需要上传大文件,可以使用
uploadStream方法替代uploadFile,支持分块上传
问题2:后端获取SAS Token,React前端完成文件上传
这个场景需要前后端配合:后端生成容器级别的SAS Token并通过接口返回,前端拿到Token后创建客户端完成上传。
后端示例(Node.js)
首先后端需要生成容器级SAS Token(这里用账户密钥生成,也可以用Azure AD认证):
const { BlobServiceClient } = require("@azure/storage-blob"); const express = require("express"); const app = express(); // 替换成你的存储账户信息 const accountName = "your-storage-account"; const accountKey = "your-storage-account-key"; const containerName = "your-container"; // 生成容器SAS Token的函数 async function generateContainerSASToken() { const connectionString = `DefaultEndpointsProtocol=https;AccountName=${accountName};AccountKey=${accountKey};EndpointSuffix=core.windows.net`; const blobServiceClient = BlobServiceClient.fromConnectionString(connectionString); const containerClient = blobServiceClient.getContainerClient(containerName); // 生成SAS Token,设置权限和过期时间 const sasUrl = await containerClient.generateSasUrl({ permissions: "w", // 只给写权限,遵循最小权限原则 expiresOn: new Date(Date.now() + 3600 * 1000), // 1小时后过期 }); // 提取SAS Token部分(去掉前面的容器URL) return sasUrl.split("?")[1]; } // 暴露接口供前端获取SAS Token app.get("/api/get-container-sas", async (req, res) => { try { const sasToken = await generateContainerSASToken(); res.json({ sasToken }); } catch (error) { res.status(500).json({ error: "生成SAS Token失败" }); } }); app.listen(3001, () => console.log("后端服务运行在端口3001"));
前端React示例
前端安装SDK后,通过接口获取SAS Token,然后处理用户选择的文件进行上传:
npm install @azure/storage-blob
import { useState } from "react"; import { ContainerClient } from "@azure/storage-blob"; function BlobUploader() { const [selectedFile, setSelectedFile] = useState(null); const [uploadStatus, setUploadStatus] = useState(""); // 从后端获取SAS Token const fetchSASToken = async () => { const response = await fetch("http://localhost:3001/api/get-container-sas"); const data = await response.json(); return data.sasToken; }; // 处理文件选择 const handleFileChange = (e) => { setSelectedFile(e.target.files[0]); setUploadStatus(""); }; // 执行上传 const handleUpload = async () => { if (!selectedFile) { setUploadStatus("请先选择要上传的文件"); return; } try { setUploadStatus("正在获取上传授权..."); const sasToken = await fetchSASToken(); const accountName = "your-storage-account"; const containerName = "your-container"; const containerUrl = `https://${accountName}.blob.core.windows.net/${containerName}?${sasToken}`; // 创建容器客户端 const containerClient = new ContainerClient(containerUrl); const blobName = selectedFile.name; const blockBlobClient = containerClient.getBlockBlobClient(blobName); setUploadStatus("正在上传文件..."); // 上传File对象(前端用uploadData方法,不能用uploadFile) const uploadResult = await blockBlobClient.uploadData(selectedFile); setUploadStatus(`文件上传成功!ETag: ${uploadResult.etag}`); } catch (error) { setUploadStatus(`上传失败: ${error.message}`); console.error("上传错误详情:", error); } }; return ( <div style={{ padding: "20px" }}> <input type="file" onChange={handleFileChange} /> <button onClick={handleUpload} disabled={!selectedFile} style={{ marginLeft: "10px" }}> 上传到Azure Blob </button> <p style={{ marginTop: "10px", color: uploadStatus.includes("成功") ? "green" : "red" }}> {uploadStatus} </p> </div> ); } export default BlobUploader;
关键注意点:
- 后端生成SAS Token时遵循最小权限原则,只给必要的权限(比如只写
w),避免安全风险 - 前端要处理跨域问题,确保后端配置了CORS允许前端域名访问
- 如果上传大文件,可以考虑添加进度监听,
uploadData方法支持传入onProgress回调
内容的提问来源于stack exchange,提问作者Auston Barboza
相关产品推荐
相关产品推荐

