【问题标题】:Extend token expiration when uploading large blobs on Azure Blob Storage在 Azure Blob 存储上上传大型 Blob 时延长令牌过期时间
【发布时间】:2021-10-21 15:18:54
【问题描述】:

我有一个 API,它为给定的 blob 名称生成并返回 SAS 令牌。然后在我的前端应用程序中,我使用 API 提供的响应(凭据)以及通过浏览器直接选择的文件来处理上传。

我正在使用 blockBlobClient.uploadData 函数。这工作正常并且上传成功完成,但是我注意到 SAS 令牌被重用于作为该 blob 的一部分上传和处理的所有块(我需要为 > 1GB 的文件做好准备),因此如果我的服务器返回一个 5 分钟的过期令牌,而我的用户的连接速度很慢或部分中断,文件可能需要 5 分钟以上才能完成上传,这最终会从 Azure Blob API 向浏览器抛出错误,并且文件上传将停止。

我知道,一种方法当然是发行寿命更长的令牌来解决这些情况,或者根据文件大小设置过期时间;但我想知道是否有一种有效且不那么复杂的方法可以以某种方式延长令牌的到期时间(不会丢失我当前对该 blob 的上传进度),以便即使达到第一个到期时间,文件也可以正确上传.到目前为止还没有在文档中找到任何内容。

我将 NodeJs 用于我的后端 API,并带有 @azure/storage-blob npm 包(我也在我的前端应用程序中使用它)

希望这已经足够清楚了。

感谢您提供的任何帮助!

【问题讨论】:

    标签: javascript file-upload azure-blob-storage sas-token


    【解决方案1】:

    解决方案 1: 注入新的 SAS 以进行持续上传。有时 SAS 会在大型上传完成之前过期,对于这种情况,我们希望在上传期间请求新的 SAS 令牌,而不是开始新的上传。

    尝试使用此代码更新 SAS 以上传大文件。

    async function upload() {
      const sasStore = new SasStore();
    
      const pipeline = Azure.StorageURL.newPipeline(
        new Azure.AnonymousCredential()
      );
      // Inject SAS update policy factory into current pipeline
      pipeline.factories.unshift(new SasUpdatePolicyFactory(sasStore));
    
      const url = "https://jsv10.blob.core.windows.net/mycontainer/myblob";
      const blockBlobURL = new Azure.BlockBlobURL(
        `${url}${await sasStore.getValidSASForBlob(url)}`, // A SAS should start with "?"
        pipeline
      );
    
      const file = document.getElementById("file").files[0];
      await Azure.uploadBrowserDataToBlockBlob(
        Azure.Aborter.none,
        file,
        blockBlobURL,
        {
          maxSingleShotSize: 4 * 1024 * 1024
        }
      );
    }
    / azblob is default exported entry when importing Azure Storage Blob SDK by <script src="azure-storage.blob.js"></script>
    // You can also import SDK by npm package with const Azure = require("@azure/storage-blob")
    const Azure = azblob;
    
    // SasStore is a class to cache SAS for blobs
    class SasStore {
      constructor() {
        this.sasCache = {};
      }
    
      // Get a valid SAS for blob
      async getValidSASForBlob(blobURL) {
        if (
          this.sasCache[blobURL] &&
          this.isSasStillValidInNext2Mins(this.sasCache[blobURL])
        ) {
          return this.sasCache[blobURL];
        } else {
          return (this.sasCache[blobURL] = await this.getNewSasForBlob(blobURL));
        }
      }
    
    
    // Return true if "se" section in SAS is still valid in next 2 mins
      isSasStillValidInNext2Mins(sas) {
        const expiryStringInSas = new URL(`http://host${sas}`).searchParams.get(
          "se"
        );
        return new Date(expiryStringInSas) - new Date() >= 2 * 60 * 1000;
      }
    
      // Get a new SAS for blob, we assume a SAS starts with a "?"
      async getNewSasForBlob(blobURL) {
        // TODO: You need to implement this
        return "?newSAS";
      }
    }
    
    class SasUpdatePolicyFactory {
      constructor(sasStore) {
        this.sasStore = sasStore;
      }
      create(nextPolicy, options) {
        return new SasUpdatePolicy(nextPolicy, options, this.sasStore);
      }
    }
    
    class SasUpdatePolicy extends Azure.BaseRequestPolicy {
      constructor(nextPolicy, options, sasStore) {
        super(nextPolicy, options);
        this.sasStore = sasStore;
      }
    
      async sendRequest(request) {
        const urlObj = new URL(request.url);
        const sas = await this.sasStore.getValidSASForBlob(
          `${urlObj.origin}${urlObj.pathname}`
        );
        new URL(`http://hostname${sas}`).searchParams.forEach((value, key) => {
          urlObj.searchParams.set(key, value);
        });
    
        // Update request URL with latest SAS
        request.url = urlObj.toString();
    
        return this._nextPolicy.sendRequest(request);
      }
    }
    

    关注github 代码了解更多详情 .要创建新的 SAS,请参考thread

    解决方案 2: 不上传大文件,而是以chunks[方法将大文件拆分成更小的文件]上传文件。分块上传文件,这样就可以上传更大的文件,而无需一次性完全读取。

    更多详情请参考document

    【讨论】:

      猜你喜欢
      • 2021-12-31
      • 2017-05-04
      • 1970-01-01
      • 2015-06-16
      • 2021-01-01
      • 2019-04-06
      • 2014-08-23
      • 2018-11-17
      • 2016-11-26
      相关资源
      最近更新 更多