解決策 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:
大きなファイルをアップロードする代わりに、ファイルをチャンクでアップロードします[大きなファイルを小さなサイズに分割する方法]。ファイルをチャンクでアップロードして、大きなファイルを一度に完全に読み取らずにアップロードできるようにします。
詳細はこのドキュメントを参照してください