You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.12 04:10:00