Kode
Kode

Reputation: 3215

Azure Blob Image Upload 405 (The resource doesn't support specified Http verb)

I am attempting to upload an image (an HTML5 canvas converted to an image which is working as intended) to Azure Blob Storage using JavaScript. At this stage, I am less concerned with file size and most concerned with being able to post the file to Azure Blob Storage. I have read a lot of different articles about SAS and for the intents of testing I have a public container, but need to learn how to generate SAS. At this point, I just need to be able to post. I have configured my blob account with CORS as follows:

Allowed Origins: http://localhost:50045
Allowed Methods: DELETE,GET,NONE,POST,PUT
Allowed Headers: content-length,accept,x-ms-*
Exposed Headers: x-ms-*
Max Age (seconds): 10000

When I use the following upload code, which is working to upload to a separate vendors Web Service, I get the following error:

405 (The resource doesn't support specified Http Verb.)

Here is my code:

$scope.reRender = function () {
    var canvasImage = document.getElementById("c");
    var img = canvasImage.toDataURL("image/png");
    var filename = 'Test';

    var formdata = new FormData();
    formdata.append(filename, img);

    var send = function (blob) {
        var filename = 'Test.png';
        var formdata = new FormData();
        formdata.append('File1', blob, filename);

        $.ajax({
            url: 'http://myblobaccount.blob.core.windows.net/blob1',
            type: "POST",
            data: formdata,
            mimeType: "multipart/form-data",
            processData: false,
            contentType: false,
            crossDomain: true,
            success: function (result) {
                console.log("Upload to Azure complete!");
            },
            error: function (error) {
                console.log("Something went wrong!");
            }
        })
    }

    var canvasImage = document.getElementById("c");
    if (!canvasImage.toBlob) {
        var dataURL = canvasImage.toDataURL();
        var bytes = atob(dataURL.split(',')[1])
        var arr = new Uint8Array(bytes.length);
        for (var i = 0; i < bytes.length; i++) {
            arr[i] = bytes.charCodeAt(i);
        }
        send(new Blob([arr], { type: 'image/png' }));
    }
    else
        canvasImage.toBlob(send);
}

Does Azure Blob Storage not support a POST? Or is my upload code not in alignment with what Azure is looking for to POST the image file into "blob1"?

Upvotes: 1

Views: 3798

Answers (3)

Serhii Matvienko
Serhii Matvienko

Reputation: 312

You must get SASToken and add it to your path,

use type: "PUT",

use headers: [{ name: 'x-ms-blob-type', value: 'BlockBlob' }]

Something like this:

<code> 
import { Injectable } from '@angular/core';
import { FileUploader, FileItem, Headers } from 'ng2-file-upload';
import { Http } from '@angular/http';


@Injectable()
export class Uploader {
    public uploader: FileUploader = new FileUploader({ url: URL, method: 'PUT' });
    public hasBaseDropZoneOver: boolean = false;
    public files: FileItem[] = this.uploader.queue;

    public r: Response;

    constructor(private httpClient: Http){}

    public getUploader(): FileUploader {
        return this.uploader;
    }

    public fileOverBase(e: any): void {
        this.hasBaseDropZoneOver = e;
    }    

    public uploadAll(): void {

        this.httpClient.get(getToken)
            .subscribe(
            result => {
                if (result.ok) {

                    for (var n = 1; n <= this.files.length; n++) {                        

                        let fullUrl = URL + this.files[n].file.name + result.json();
                        console.log('--> send url ' + fullUrl);

                        this.uploader.setOptions({
                            url: fullUrl, method: 'PUT',
                            headers: [{ name: 'x-ms-blob-type', value: 'BlockBlob' }]
                        });

                        this.uploader.uploadItem(this.files[n]);
                    }
                }
                else {
                    console.log('--> get token error ' + result.statusText);
                }                
            });                
    }

    public cancelAll(): void {
        this.uploader.cancelAll();
    }

    public clearQueue(): void {
        this.uploader.clearQueue();
    }    
}
</code> 

Upvotes: 1

Andy Huang
Andy Huang

Reputation: 1

The below is my CORS properties setting which work to me, hope this will be helpful.

Allowed Origins: *
Allowed Methods: GET,PUT
Allowed Headers: *
Exposed Headers: *
Max Age (seconds): 200

Upvotes: 0

Akash Kava
Akash Kava

Reputation: 39956

Azure blob storage does not support HTML form based file upload, AWS S3 supports this. So POST is not supported by Azure Blob storage. I think it supports PUT, you can try PUT.

But doing all this in JavaScript is dangerous, anyone can put items after acquiring necessary shared signature. If you are not providing shared access signature, blob storage will not allow any operation at all.

Instead you must upload file to your server, PHP, ASP or anything and then connect to Azure via its SDK and save it. Or create a shared signature with rights.

Upvotes: 2

Related Questions