解决方案 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:
不要上传大文件,而是分块上传文件[方法将大文件拆分为更小的尺寸]。以块的形式上传文件,以便可以上传更大的文件而无需一次性完全读取它们。
更多详细信息请参阅此文档