Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to cancel Azure blob upload (multiple files)

Azure blob service allows us to pass a cancel filter which can be used to cancel an upload (Example: How to cancel an upload started with BlobService.createBlockBlobFromBrowserFile?). It works fine for an individual upload, but it doesn't work well for situations when client is trying to upload multiple files. The problem is that cancel filter is an attribute of service itself, not an individual upload, so cancelling one upload cancels all the uploads. Is there any way (via typescript/JavaScript client) to cancel one upload while letting others go undisturbed?

like image 276
klone Avatar asked Sep 17 '25 04:09

klone


1 Answers

The package azure-storage is legacy. Now Microsoft suggest customers use the new sdk V12 @azure/storage-blob. if you use the new SDK, we can use AbortController to cancel one operation. For more details, please refer to here.

For example (I test it in angular application)

  1. install Azure storage SDk
npm install @azure/storage-blob @azure/abort-controller
  1. Add the following code in polyfills.ts
(window as any).global = window;
(window as any).process = require( 'process' );
(window as any).Buffer = require( 'buffer' ).Buffer;
  1. Html
<label class="btn btn-default">
  <input type="file"
       id="file"
       multiple
       (change)="onFileChange($event)">
</label>


<div *ngFor="let item of fileInfos" class="mb-2">
  <span>{{ item.file.name }}</span>
  <div class="progress">
    <div
      class="progress-bar progress-bar-info progress-bar-striped"
      role="progressbar"
      attr.aria-valuenow=" {{ item.value }}"
      aria-valuemin="0"
      aria-valuemax="100"
      [ngStyle]="{ width: item.value + '%' }"
    >
      {{ item.value }}%
    </div>
  </div>

  <button class="btn btn-primary"  (click)='item.upload()'>upload</button>
  <button class="btn btn-primary"  (click)='item.cancel()'>cancel</button>

</div>
  1. Define FileInfo calss
import {AbortController} from '@azure/abort-controller'
import {BlobServiceClient,AnonymousCredential} from  '@azure/storage-blob'

export class FileInfo{

    file : File
    value=0
    private  controller = new AbortController()
    constructor(message: File) {
        this.file = message;
      }

    async upload(){
        try {
            
        const blobServiceClient= new BlobServiceClient('https://<accountNmae>.blob.core.windows.net/?<sas token>',
new AnonymousCredential)

        const containerClient= blobServiceClient.getContainerClient('<>') 
        const blob= containerClient.getBlockBlobClient(this.file.name)
        console.log(`start uploading file ${this.file.name}`)
        const total =this.file.size
        await blob.uploadData(this.file,{
            abortSignal: this.controller.signal,
            blobHTTPHeaders:{blobContentType: this.file.type},
            blockSize: 4*1024*1024,
            onProgress : (ev) =>{
                console.log(`You have uploaded ${ev.loadedBytes} bytes`);
                this.value=Math.round(100 * ev.loadedBytes/ total);
            }
        })
        console.log(` upload file ${this.file.name} successfully`)
        } catch (error) {
            console.log(`cannot upload file ${this.file.name}, it return error ${error}`)
        }
        
    }

    cancel(){
        this.controller.abort()
        console.log(`cancel uploading file ${this.file.name}`) 
    }
}
  1. Component
...
fileInfos: Array<FileInfo> =[]
  onFileChange(event:any) {
   this.fileInfos=[]
    for (var i = 0; i < event.target.files.length; i++) { 
        var file =event.target.files[i]
       
        this.fileInfos.push( new FileInfo(file))
      }
  }

enter image description here enter image description here

like image 127
Jim Xu Avatar answered Sep 18 '25 16:09

Jim Xu