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

如何通过带SAS Token的PUT请求向Azure Blob Storage上传10GB+大文件?

解决Azure Blob Storage大文件(10GB+)SAS URL上传问题

问题根源

你遇到的413错误是因为Azure Blob Storage的单个PUT请求上传Blob的大小限制:对于存储服务版本2016-05-31,单个Blob的直接PUT上传上限是4GB,超过这个大小必须使用**分块上传(Block Blob Upload)**方案,该方案支持最大5TB的Blob上传(每个块最大100MB,最多50000个块)。

解决方案步骤

1. 调整后端SAS Token生成逻辑

确保SAS Token具备分块上传所需权限,并升级存储服务版本以获得更好兼容性:

代码优化(修正原变量错误+适配分块上传)

function generate_signed_url(BLOB_NAME) {
    const ACCOUNT_NAME = process.env.AZURE_BLOB_STORAGE_ACCOUNT_NAME;
    const CONTAINER_NAME = process.env.AZURE_BLOB_STORAGE_CONTAINER_NAME;
    const ACCESS_KEY = process.env.AZURE_BLOB_STORAGE_ACCESS_KEY;

    const sharedKeyCredential = new StorageSharedKeyCredential(ACCOUNT_NAME, ACCESS_KEY);
      
    // 延长SAS有效期,避免大文件上传超时(设置为4小时)
    const expDate = new Date(new Date().valueOf() + 14400 * 1000);

    // 升级存储服务版本到2021-06-08,支持更多分块上传特性
    const blobSAS = generateBlobSASQueryParameters({
      containerName: CONTAINER_NAME,
      blobName: BLOB_NAME,
      // 明确包含分块所需权限:read、add、create、write、delete
      permissions: BlobSASPermissions.parse("racwd"),
      startsOn: new Date(),
      expiresOn: expDate,
      ipRange: { start: "0.0.0.0", end: "255.255.255.255" },
      protocol: SASProtocol.Https, // 建议仅用HTTPS提升安全性
      version: "2021-06-08"
    }, sharedKeyCredential).toString();

    // 修正原代码变量错误:AZURE_CONTAINER -> CONTAINER_NAME,AZURE_BLOB -> BLOB_NAME,containerSAS -> blobSAS
    const SaSURL = `https://${ACCOUNT_NAME}.blob.core.windows.net/${CONTAINER_NAME}/${BLOB_NAME}?${blobSAS}`;
    
    console.log(`SAS URL for blob is: ${SaSURL}`);
    return SaSURL;
}

2. 前端实现分块上传逻辑

使用Axios实现分块上传,核心步骤为分割文件、上传每个块、提交块列表组装完整Blob:

// 分块上传核心函数,默认100MB每块
async function uploadLargeFileWithSAS(sasUrl, file, chunkSize = 100 * 1024 * 1024) { 
    const chunkCount = Math.ceil(file.size / chunkSize);
    const blockIds = [];

    // 逐个上传分块
    for (let i = 0; i < chunkCount; i++) {
        const start = i * chunkSize;
        const end = Math.min(start + chunkSize, file.size);
        const chunk = file.slice(start, end);
        
        // 生成Base64编码的唯一块ID,需保证长度一致
        const blockId = btoa(`block-${String(i).padStart(6, '0')}`);
        blockIds.push(blockId);

        // 构造块上传URL:在原SAS URL基础上添加块操作参数
        const [blobBaseUrl, sasQuery] = sasUrl.split('?');
        const chunkUploadUrl = `${blobBaseUrl}?comp=block&blockid=${blockId}&${sasQuery}`;

        await axios({
            method: 'PUT',
            url: chunkUploadUrl,
            data: chunk,
            headers: {
                'Content-Length': chunk.size
            }
        });
    }

    // 提交块列表,组装成完整Blob
    const blockListBody = `<?xml version="1.0" encoding="utf-8"?>
<BlockList>
    ${blockIds.map(id => `<Latest>${id}</Latest>`).join('')}
</BlockList>`;

    const [blobBaseUrl, sasQuery] = sasUrl.split('?');
    const commitUrl = `${blobBaseUrl}?comp=blocklist&${sasQuery}`;
    await axios({
        method: 'PUT',
        url: commitUrl,
        data: blockListBody,
        headers: {
            'Content-Type': 'application/xml'
        }
    });

    console.log('大文件上传完成');
}

// 调用示例
// uploadLargeFileWithSAS(SaSUrl, file);

3. 额外优化建议

  • 断点续传:记录已上传的块ID,下次上传时跳过已完成的块
  • 进度监控:监听每个块的上传进度,汇总成整体上传进度
  • 错误重试:对块上传失败的请求添加重试逻辑,提升稳定性
  • SAS有效期:根据文件大小调整SAS有效期,避免上传过程中Token过期

内容的提问来源于stack exchange,提问作者Kid_Learning_C

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.16 10:49:54