I have an MVC application that allows a user to upload a resource to blob storage with a dynamically generated SAS. A user will select a file and click upload. When upload is clicked, an ajax call is sent to a controller action that will generate an SAS for the container and return a string which is the URI for the blob that is going to be uploaded with the signature appended. This works perfectly and returns the correct URI with SAS. I then have another ajax call that will PUT the data from the file to Azure Blob Storage using the URI that was returned. When this executes I get a javascript runtime error in the Jquery.min file that says "0x80070005 Access is Denied".
I wanted to make sure I had coded this correctly and that my SAS was right so I ran it through Runscope (I had the MVC controller action modify the URI to go through my Runscope account). If I copied the URI and manually set the headers that I am setting in the ajax call, it worked. And the permission settings work. With the SAS that I generated I can access the file, without it I cannot. If I let it run through my javascript file with the ajax call it failed and returned a 405 error. Here is my ajax call and then my two different requests sent with Runscope.
I used this article http://gauravmantri.com/2013/02/16/uploading-large-files-in-windows-azure-blob-storage-using-shared-access-signature-html-and-javascript/#comment-1700 as a guide for uploading the file in chunks. The following ajax call will execute for each block uploaded, but it fails on the first try.
var uri = submitUri + "&comp=block&blockid=" + blockIds[blockIds.length - 1];
var requestData = new Uint8Array(evt.target.result);
$.ajax({
url: uri,
type: "PUT",
data: requestData,
processData: false,
beforeSend: function(xhr) {
xhr.setRequestHeader("x-ms-blob-type", "BlockBlob");
xhr.setRequestHeader("Content-Length", requestData.length);
},
success: function() {
// successful stuff here
uploadFileInBlocks();
}
error: function (xhr, desc, err) {
// error stuff here
}
});
And here are my Runscope results:
Successful manual request:
PUT https://<myaccount>.blob.core.windows.net/trainingcourseresources/1002/georgewashington.jpg?sr=c&sp=rw&sig=GI+HN1hTEiyTG9Kz1OIBIcArAEkeZWyxI4v7OmMuEsA=&sv=2012-02-12&se=2013-09-17T13:19:52Z
HEADERS
Accept: */*
Accept-Encoding: gzip, deflate, compress
Connection: close
Host: atlastestblob.blob.core.windows.net
User-Agent: runscope/0.1
X-Ms-Blob-Type: BlockBlob
QUERYSTRING
se: 2013-09-17T13:19:52Z
sig: GI+HN1hTEiyTG9Kz1OIBIcArAEkeZWyxI4v7OmMuEsA=
sp: rw
sr: c
sv: 2012-02-12
Response: 201 Created
Failed ajax request:
OPTIONS https://<myaccount>.blob.core.windows.net/trainingcourseresources/1002/cslewis.jpg?sp=rw&sr=c&blockid=YmxvY2stMDAwMDAw&sv=2012-02-12&sig=iIn/AL3eBBFlZdYoT717SMS9iDOY5PEKIdIufOle7NA=&comp=block&se=2013-09-17T13:40:00Z
HEADERS
Accept: */*
Accept-Encoding: gzip, deflate
Access-Control-Request-Headers: content-type, accept, x-ms-blob-type
Access-Control-Request-Method: PUT
Cache-Control: no-cache
Connection: close
Dnt: 1
Host: atlastestblob.blob.core.windows.net
Origin: https://localhost:44308
User-Agent: Mozilla/5.0 (compatible; MSIE 10.0; Windows NT 6.2; WOW64; Trident/6.0)
QUERYSTRING
blockid: YmxvY2stMDAwMDAw
comp: block
se: 2013-09-17T13:40:00Z
sig: iIn/AL3eBBFlZdYoT717SMS9iDOY5PEKIdIufOle7NA=
sp: rw
sr: c
sv: 2012-02-12
Response: 405 The resource doesn't support specified Http Verb