0

特定の BLOB 名の SAS トークンを生成して返す API が用意されています。次に、フロント エンド アプリケーションで、API によって提供される応答 (資格情報) と、ブラウザーから直接選択されたファイルを使用してアップロードを処理します。

blockBlobClient.uploadData関数を使用しています。これは正常に機能し、アップロードは正常に終了しますが、SAS トークンがアップロードされ、そのブロブの一部として処理されるすべてのブロックで再利用されることに気付きました (1GB を超えるファイルに備える必要があります)。 5 分の有効期限トークンがあり、ユーザーの接続が遅いか部分的に中断された場合、ファイルのアップロードが完了するまでに 5 分以上かかる場合があり、最終的に Azure Blob API からブラウザーにエラーがスローされ、ファイルのアップロードが停止します。

もちろん、これらのシナリオを説明するために、より長い有効期間のトークンを発行するか、ファイル サイズに基づいて有効期限を設定するという 1 つのアプローチがあることはわかっています。しかし、最初の有効期限に達した場合でもファイルが適切にアップロードされるように、(そのブロブの現在のアップロードの進行状況を失うことなく) トークンの有効期限を延長する効率的でそれほど複雑ではない方法があるかどうかを知りたいです。 . これまでのところ、ドキュメントには何も見つかりませんでした。

バックエンド API に NodeJs を使用し、@azure/storage-blob npm パッケージ (フロントエンド アプリでも使用しています)

それが十分に明確であることを願っています。

提供できるヘルプをありがとう!

4

1 に答える 1

0

解決策 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 を作成するには、このスレッドを参照してください。

解決策 2: 大きなファイルをアップロードする代わりに、ファイルをチャンクでアップロードします[大きなファイルを小さなサイズに分割する方法]。ファイルをチャンクでアップロードして、大きなファイルを一度に完全に読み取らずにアップロードできるようにします。

詳細はこのドキュメントを参照してください

于 2021-08-21T09:24:24.400 に答える