3

I'm trying to upload an image file from an html page to azure blob storage. So far I have written a web service to create an SAS for my blob container. From this I have created a uri of the format "blob address" / "container name" / "blob name" ? "sas". I have an upload control on my html page.

I have then tried to upload the file using the following code:

var xhr = new XMLHttpRequest();
xhr.upload.addEventListener("progress", uploadProgress, false);
xhr.addEventListener("load", uploadComplete, false);
xhr.addEventListener("error", uploadFailed, false);
xhr.addEventListener("abort", uploadCanceled, false);
xhr.open("PUT", blobPath);
xhr.send(upFile.files[0]);

where blobPath is the uri as above and upFile is my html upload control.

When I try to upload a file the uploadFailed routine is triggered. So: Is this the right way to do this? How do I trap the error returned by the upload so that I can see what is going wrong?

My sas looks like: "sr=c&si=mypolicy&sig=onZTE4buyh3JEQT3%2B4cJ6uwnWX7LUh7fYQH2wKsRuCg%3D"

Any help appreciated, thanks.

Rachel Edge
  • 351
  • 2
  • 6
  • 18

2 Answers2

5

This is certainly the right way however there're a few things:

  1. You have to include x-ms-blob-type request header in your request and it's value should be BlockBlob.
  2. Also please realize that for this to work, you would need to host your HTML page in the same storage account because CORS is not supported in Azure Blob Storage as of today. So if your html page is hosted in some other domain, you would get error because of CORS.

You may find these blog posts useful for uploading blobs using SAS and AJAX:

http://coderead.wordpress.com/2012/11/21/uploading-files-directly-to-blob-storage-from-the-browser/

http://gauravmantri.com/2013/02/16/uploading-large-files-in-windows-azure-blob-storage-using-shared-access-signature-html-and-javascript/

Gaurav Mantri
  • 128,066
  • 12
  • 206
  • 241
  • Thanks, those are the blog posts I've been trying to follow to get this going. I've now swapped the upload code to the ajax call (including 'x-ms-blob-type' header) as shown in your blog post but it still doesn't work. Also, can you explain what you mean by "you would need to host your HTML page in the same storage account". My html page is running in a cloud service. The cloud service is within the same azure account as the blob storage and I have linked the cloud service to the blob storage account. Is that enough? Thanks – Rachel Edge Jul 29 '13 at 14:14
  • Upload now:'$.ajax({ url: blobPath, type: "PUT", data: upFile.files[0], processData: false, beforeSend: function (xhr) { xhr.setRequestHeader('x-ms-blob-type', 'BlockBlob'); xhr.setRequestHeader('Content-Length', upFile.files[0].size); }, success: function (data, status) { console.log(data); console.log(status); }, error: function (xhr, desc, err) { console.log(desc); console.log(err); } });' This triggers the error case but 'err' is "". – Rachel Edge Jul 29 '13 at 14:17
  • Can you please post the entire code? Since your HTML file (which is in your cloud service) and your blob storage are in different domains, you're running into CORS issue (http://en.wikipedia.org/wiki/Cross-origin_resource_sharing). In order for Ajax calls to work, both source and destination must be in the same domain and hence my comment `"you would need to host your HTML page in the same storage account`. Please try running your code by copying the HTML file in same storage account. Also you may want to trace your request/response through Fiddler. – Gaurav Mantri Jul 29 '13 at 14:38
  • I don't know how to run my html file in a storage account. I need my html page to be part of my cloud service. Can you explain further? – Rachel Edge Jul 29 '13 at 14:52
  • Is there some other way I can do this? All I need is to be able to upload a file from an html page to an azure blob (or is that not a simple thing to do?). Can I upload my file to local storage from my html page? I know how to then transfer my file from local storage to blob storage. – Rachel Edge Jul 29 '13 at 14:55
  • What you do is create a blob container in your storage account and make its ACL as either `Blob` or `Container`. Then copy your HTML file and related JavaScript files there. Then try to access that HTML page by using the URL: _http:// yourstorageaccount.blob.core.windows.net/yourblobcontainer/yourhtmlfile.html. – Gaurav Mantri Jul 29 '13 at 14:57
  • What you could do is upload the file on your web server first and then once the file is uploaded on the server, then copy it to blob storage. If you want, you could store that file into local storage (though I would not recommend it). Other alternative would be to use a Silverlight based file uploader. You may find this post useful: http://blog.smarx.com/posts/uploading-windows-azure-blobs-from-silverlight-part-1-shared-access-signatures. – Gaurav Mantri Jul 29 '13 at 15:00
  • Apologies for being dense but if I have my html pages and js files in blob storage can I still access them as part of my cloud service and how would it work when I wanted to publish my cloud package to azure? – Rachel Edge Jul 29 '13 at 15:17
  • If I want to upload a file to my web server how would I do that? That is what I first tried to do and then switched to trying to upload direct to blobs when I couldn't work out how to do that. I originally had an asp upload control which uploaded the file to azure local storage and I then transferred the file to blob storage from there. I now want to replace that with an html upload control but can't see how to get the html control to upload to local storage. I'd prefer not to use Silverlight. – Rachel Edge Jul 29 '13 at 15:26
  • I think your question has become a different question, and it wouldn't be appropriate to try to answer the new one in this comments thread. Maybe start a new question. – Mark Rendle Jul 29 '13 at 19:41
  • OK I will start a new question: 'Upload files from html to azure' – Rachel Edge Jul 30 '13 at 08:33
0

I have now found a solution that works for this problem. My upload now works as follows:

  • I read the file as a DataURL into a FileReader

  • I slice the returned string up and send each slice up to the server where it is stored in a session variable

  • Once the whole file has been sent up I call another web service which glues the slices back together and turns the result into a byte array

  • The byte array is then stored as a file in local storage in azure

  • Finally the file is transferred from local storage into blob storage

See code at:

Upload files from html to azure

Community
  • 1
  • 1
Rachel Edge
  • 351
  • 2
  • 6
  • 18