azure-blob-storageazure-storage-explorerazurite

Azurite docker image and CORS


I'm developing an Azure function application in C#. I'm trying to run the application locally and am having a large amount of difficulty around getting a file upload to work with Azurite.

The application has a frontend written in Angular. It utilizes the "@azure/storage-blob": "^12.6.0" library to upload a file to Azure storage with the following code:

      private uploadFile(audioMedia: AudioMediaDto, file: File | null, storageAccessInformation: StorageAccessInformationDto): Observable<TransferProgressEvent> {
        const sub = new Subject<TransferProgressEvent>();
        if (file) {
          const url = `${env.blobStorageUri}?${storageAccessInformation.accessToken}`;
          const blobServiceClient = new BlobServiceClient(url);
          const containerClient = blobServiceClient.getContainerClient(storageAccessInformation.containerName);
          containerClient.getBlobClient(`${storageAccessInformation.uploadDirectory}/${audioMedia.id}`)
                         .getBlockBlobClient()
                         .uploadData(
                           file,
                           {
                             onProgress: (progress: TransferProgressEvent) => sub.next(progress)
                           }
                         )
                         .then(
                           () => sub.complete(),
                           () => sub.error('')
                         );
        } else {
          sub.error('');
        }
    
        return sub.asObservable();
      }

Here is my docker-compose.yaml

    version: "3.9"
    services:
      azurite:
        image: mcr.microsoft.com/azure-storage/azurite
        command: "azurite --loose --blobHost 0.0.0.0 --blobPort 10000 --queueHost 0.0.0.0 --queuePort 10001 --location /workspace --debug /workspace/debug.log"
        ports:
          - 10010:10000
          - 10011:10001
          - 10012:10002
        volumes:
          - ./azurite:/workspace
    
      frontend:
        build: frontend
        ports:
          - 4200:4200

When I run docker-compose up, I open the Azure storage emulator and connect to my Azurite instance and then right click on the 'Blob Containers' and configure a CORS policy that looks as follows:

I create a container through Azure storage explorer and then right click on it and choose "Get Shared Access Signature...". I make the Expiry Time for a year in the future and select all of the permissions. When I click create though, I see the following error message:

Error when calling Azure Storage:'version' must be >= '2019-10-10' when providing 'x' permission.

While I believe this will be a problem, if I currently run the application as is and try to upload a document to the container, I'm getting the following message:

Access to XMLHttpRequest at 'http://localhost:10010/devstoreaccount1/container-name/src%2F0e237853-f7a9-4dc8-b892-a0eddc2688d8?sv=2018-03-28&st=2021-06-30T15%3A03%3A48Z&se=2022-07-01T15%3A03%3A00Z&sr=c&sp=c&sig=qWHZ4wpkoVZwvJbPK0r6%2Fwf%2B5LL3kBjgEc6oFm3ikUA%3D' from origin 'http://localhost:4200' has been blocked by CORS policy: Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource.

I can see that the CORS settings I applied to my container were saved though because when I look at the ./azurite/__azurite_db_blob__.json file, I see the following section in it: enter image description here

What setup/steps am I missing, that would enable me to upload a document to the azurite container running in the docker image?


Solution

  • With CORS, the values specified in AllowedHeaders and ExposedHeaders properties must match exactly with the headers sent and received respectively. A mismatch in these header values will cause CORS related errors.

    Furthermore, in my experience different browsers send/receive different headers and that would also cause CORS related errors.

    Simplest way to fix this is to set * for both AllowedHeaders and ExposedHeaders properties. What this will do is allow all headers and you will not get CORS error.