Adding File to Azure Storage Blob from Angular

烂漫一生 提交于 2020-03-23 12:14:22

问题


I'm trying to figure out how to upload an image using ngx-awesome-uploader to azure storage blob from Angular.

I'd like to be able to send it directly to azure storage blob from angular using this library. I've been able to send it to my nodejs backend no problem, but it's been challenging for me to send it directly to blob storage instead. Can anyone provide a working example of how to do this? I appreciate any help!

Choose Simple Demo in stackblitz. Not Advanced Demo

Stackblitz example of ngx awesome uploader

The file is passed to this. (Console output below code)

import { FilePreviewModel } from 'ngx-awesome-uploader';
import { HttpRequest, HttpClient, HttpEvent, HttpEventType } from '@angular/common/http';
import { map } from 'rxjs/operators';
import { Observable } from 'rxjs';
import { FilePickerAdapter } from 'ngx-awesome-uploader';

export class DemoFilePickerAdapter extends FilePickerAdapter {
  constructor(private http: HttpClient) {
    super();
  }
  public uploadFile(fileItem: FilePreviewModel) {
    const form = new FormData();
    form.append('file', fileItem.file);

   console.log("FILE OUTPUT");
    console.log(fileItem.file);


//need to replace everything below with code to add to storage blob

    const api = 'https://demo-file-uploader.free.beeceptor.com';
    const req = new HttpRequest('POST', api, form, {reportProgress: true});
    return this.http.request(req)
    .pipe(
      map( (res: HttpEvent<any>) => {
          if (res.type === HttpEventType.Response) {
          return res.body.id.toString();
        } else if (res.type ===  HttpEventType.UploadProgress) {
            // Compute and show the % done:
            const UploadProgress = +Math.round((100 * res.loaded) / res.total);
            return UploadProgress;
        }
      })
      );
  }

}

the console.output of FILE OUTPUT is


回答1:


According to my test, if you want to upload file to Azure blob, please refer to the following steps

  1. install Azure storage SDk
npm install @azure/storage-blob
  1. Update app.component.html File
<div class="form-group">
  <label for="file">Choose File</label>
  <input type="file"
         id="file"
         (change)="onFileChange($event)">
</div>


  1. Update Environment.ts
export const environment = {
  production: false,
  accountName : "<account name>",
  containerName:"",
   key:""
};
  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. Add the following code in app.component.ts
import { Component } from '@angular/core';
import {BlobServiceClient,AnonymousCredential,newPipeline } from '@azure/storage-blob';
import { environment } from './../environments/environment';
@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.css']
})
export class AppComponent {
  title = 'web1';
  currentFile : File =null;
  onFileChange(event) {
    this.currentFile = event.target.files[0];
   console.log(this.currentFile.name)
    console.log(this.currentFile.type)
// generate account sas token
  const accountName =environment.accountName;
  const key=environment.key;
  const start = new Date(new Date().getTime() - (15 * 60 * 1000));
  const end = new Date(new Date().getTime() + (30 * 60 * 1000));
const signedpermissions = 'rwdlac';
  const signedservice = 'b';
  const signedresourcetype = 'sco';
  const signedexpiry = end.toISOString().substring(0, end.toISOString().lastIndexOf('.')) + 'Z';
  const signedProtocol = 'https';
  const signedversion = '2018-03-28';

  const StringToSign =
      accountName+ '\n' +
      signedpermissions + '\n' +
      signedservice + '\n' +
      signedresourcetype + '\n' +
       '\n' +
      signedexpiry + '\n' +
       '\n' +
      signedProtocol + '\n' +
signedversion + '\n';
  const crypto =require('crypto')
   const sig = crypto.createHmac('sha256', Buffer.from(key, 'base64')).update(StringToSign, 'utf8').digest('base64');
  const sasToken =`sv=${(signedversion)}&ss=${(signedservice)}&srt=${(signedresourcetype)}&sp=${(signedpermissions)}&se=${encodeURIComponent(signedexpiry)}&spr=${(signedProtocol)}&sig=${encodeURIComponent(sig)}`;
  const containerName=environment.containerName;

            const pipeline =newPipeline (new AnonymousCredential(),{
            retryOptions: { maxTries: 4 }, // Retry options
            userAgentOptions: { userAgentPrefix: "AdvancedSample V1.0.0" }, // Customized telemetry string
            keepAliveOptions: {
                // Keep alive is enabled by default, disable keep alive by setting false
                enable: false
            }
            });

            const blobServiceClient =new BlobServiceClient(`https://${accountname}.blob.core.windows.net?${sasToken}`,
                                                             pipeline  )
            const containerClient =blobServiceClient.getContainerClient(containerName)
            if(!containerClient.exists()){
            console.log("the container does not exit")
            await containerClient.create()

            }
            const client = containerClient.getBlockBlobClient(this.currentFile.name)
           const response = await client.uploadBrowserData(this.currentFile,{
                  blockSize: 4 * 1024 * 1024, // 4MB block size
                  concurrency: 20, // 20 concurrency
                  onProgress: (ev) => console.log(ev),
                  blobHTTPHeaders :{blobContentType:this.currentFile.type}
                  })
    console.log(response._response.status)
 }
}

  1. Configure CORS for Azure storage
Allowed origins: *
Allowed verbs: DELETE,GET,HEAD,MERGE,POST,OPTIONS,PUT
Allowed headers: *
Exposed headers: *
Maximum age (seconds): 86400
  1. Test. I upload a pdf file

Regarding how to configure CORS, please refer to the following steps

  1. Sign in Azure Portal.

  2. Select the Azure account you use

  3. Configure CORS


Update

If you cannot use function createHmac, you can try to use crypto-js. The detailed steps are as below

  1. install sdk
npm install crypto-js --save
npm install @types/crypto-js --save-dev
  1. Update code in the in app.component.ts
...
import * as CryptoJS from 'crypto-js';


...
export class AppComponent {
  title = 'web1';
  currentFile : File =null;
  onFileChange(event) {
    this.currentFile = event.target.files[0];
   console.log(this.currentFile.name)
    console.log(this.currentFile.type)
// generate account sas token
  const accountName =environment.accountName;
  const key=environment.key;
  const start = new Date(new Date().getTime() - (15 * 60 * 1000));
  const end = new Date(new Date().getTime() + (30 * 60 * 1000));
const signedpermissions = 'rwdlac';
  const signedservice = 'b';
  const signedresourcetype = 'sco';
  const signedexpiry = end.toISOString().substring(0, end.toISOString().lastIndexOf('.')) + 'Z';
  const signedProtocol = 'https';
  const signedversion = '2018-03-28';

  const StringToSign =
      accountName+ '\n' +
      signedpermissions + '\n' +
      signedservice + '\n' +
      signedresourcetype + '\n' +
       '\n' +
      signedexpiry + '\n' +
       '\n' +
      signedProtocol + '\n' +
signedversion + '\n';

 var str =CryptoJS.HmacSHA256(StringToSign,CryptoJS.enc.Base64.parse(key));
 var sig = CryptoJS.enc.Base64.stringify(str);


  const sasToken =`sv=${(signedversion)}&ss=${(signedservice)}&srt=${(signedresourcetype)}&sp=${(signedpermissions)}&se=${encodeURIComponent(signedexpiry)}&spr=${(signedProtocol)}&sig=${encodeURIComponent(sig)}`;
  const containerName=environment.containerName;

            const pipeline =newPipeline (new AnonymousCredential(),{
            retryOptions: { maxTries: 4 }, // Retry options
            userAgentOptions: { userAgentPrefix: "AdvancedSample V1.0.0" }, // Customized telemetry string
            keepAliveOptions: {
                // Keep alive is enabled by default, disable keep alive by setting false
                enable: false
            }
            });

            const blobServiceClient =new BlobServiceClient(`https://${accountname}.blob.core.windows.net?${sasToken}`,
                                                             pipeline  )
            const containerClient =blobServiceClient.getContainerClient(containerName)
            if(!containerClient.exists()){
            console.log("the container does not exit")
            await containerClient.create()

            }
            const client = containerClient.getBlockBlobClient(this.currentFile.name)
           const response = await client.uploadBrowserData(this.currentFile,{
                  blockSize: 4 * 1024 * 1024, // 4MB block size
                  concurrency: 20, // 20 concurrency
                  onProgress: (ev) => console.log(ev),
                  blobHTTPHeaders :{blobContentType:this.currentFile.type}
                  })
    console.log(response._response.status)
 }
}


来源:https://stackoverflow.com/questions/60533341/adding-file-to-azure-storage-blob-from-angular

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!