javascript - Bad format when i put an image to azure blob storage with XMLHttpRequest and SAS -
i have set in spa application ability send files azure blob storage.
to used xmlhttprequest , formdata (my users on computers managed company , have access html5). in order manage security, sending of each file preceded call method of web api obtain shared access signature.
i forward content-type of file other information headers.
everything happens better, files correctly sent , saved in azure blob storage, during transfer, image files seem "altered".
they present, can download them , read them after download, can not open them directly img tag.
on other hand if send same image file via microsoft azure storage explorer, there no problem, image recognized in img tag. however, in 1 case in other, content-type marked "image / jpeg". noticeable difference md5 not same between these 2 mailings while same file of origin.
from findings seems there text added beginning , end of file when sending via xmlhttprequest.
i explain code can guide me: note 1 : use typescript (but javascript solution suit me) , promise. note 2 : have resolve cors problems. note 3 : i'm using azure storage emulator, try normal azure service , problem same.
here text added in image in chrome:
------webkitformboundarykj5ck88faawjd4av content-disposition: form-data; name="file1"; filename="test.jpg" content-type: image/jpeg [image content] ------webkitformboundarykj5ck88faawjd4av-- my web api :
[route(@"api/storage/filesas/customers/{id:int}")] public async task<ihttpactionresult> getfilesas(int id, string filename, long? filesize = 0, string contenttype = null) { if (string.isnullorwhitespace(filename)) this.modelstate.addmodelerror("filename", "file name i"); if (!filesize.hasvalue || filesize.value > maxfilesize) this.modelstate.addmodelerror("filesize", "file size exceeded"); if (!this.modelstate.isvalid) return badrequest(this.modelstate); var serverurl = configurationmanager.appsettings[server_url]; var container = configurationmanager.appsettings[container_name]; sharedaccessblobpolicy policy = new sharedaccessblobpolicy() { permissions = sharedaccessblobpermissions.write, sharedaccessstarttime = datetime.utcnow.addminutes(-60), sharedaccessexpirytime = datetime.utcnow.addminutes(60), }; cloudblockblob blobfile = blobcontainer.getblockblobreference(path.combine("customers", id.tostring(), filename)); var exists = await blobfile.existsasync(); if (exists) { await blobfile.snapshotasync(); } var signature = blobfile.getsharedaccesssignature(policy); return content<string>(httpstatuscode.created, path.combine(serverurl, container, blobfile.name + signature)); } my typescript file :
context.storage.getfilesas(customerid, file) .then((response: interfaces.result<string>) => { let sasurl = response.data; let formdata = new formdata(); formdata.append("file1", file, file.name); var xhr = new xmlhttprequest(); xhr.upload.onprogress = (event) => { if (event.total > 0) this.progress(event.loaded * 100 / event.total); }; xhr.onloadstart = function (e) { } xhr.onloadend = (e) => { this.progress(0); } xhr.open("put", sasurl, true); xhr.setrequestheader('x-ms-blob-type', 'blockblob'); xhr.setrequestheader('content-type', file.type); xhr.setrequestheader('x-ms-blob-content-type', file.type); xhr.setrequestheader('x-ms-version', "2016-05-31"); xhr.setrequestheader('x-ms-meta-customerid', customerid); xhr.setrequestheader('x-ms-meta-userid', context.user.user.id.tostring()); xhr.setrequestheader('x-ms-meta-username', context.user.user.name); xhr.send(formdata); }) })).catch((error) => { console.log(error); }); file come here :
let fileinputelement1: htmlinputelement = <htmlinputelement>document.getelementbyid("file1"); let file = fileinputelement1.files[0]; my html part : (i'm using knockout)
<form method="put" target="_blank" enctype="multipart/form-data"> <input type="file" name="name" value="" id="file1" /> <button data-bind="click:send"> send</button> </form> if have idea ? ...
thank's in advance.
thank's gaurav mantri, point me right, here modifications (only because use typescript) :
context.storage.getfilesas(customerid, file) .then((response: interfaces.result<string>) => { let sasurl = response.data; var xhr = new xmlhttprequest(); xhr.upload.onprogress = (event) => { if (event.total > 0) this.progress(event.loaded * 100 / event.total); }; xhr.onloadstart = function (e) { } xhr.onloadend = (e) => { this.progress(0); } let reader = new filereader(); reader.readasarraybuffer(file); reader.onloadend = (event) => { let target = <filereader>event.target; if (target.readystate == reader.done) { var requestdata = new uint8array(target.result); xhr.open("put", sasurl, true); xhr.responsetype = "blob"; xhr.setrequestheader('x-requested-with', 'xmlhttprequest'); xhr.setrequestheader('x-file-name', file.name); xhr.setrequestheader('x-ms-blob-type', 'blockblob'); xhr.setrequestheader('content-type', file.type || 'application/octet-stream'); xhr.setrequestheader('x-ms-blob-content-type', file.type || 'application/octet-stream'); xhr.setrequestheader('x-ms-version', "2016-05-31"); xhr.setrequestheader('x-ms-meta-customerid', customerid); xhr.setrequestheader('x-ms-meta-userid', context.user.id.tostring()); xhr.setrequestheader('x-ms-meta-username', context.user.name); xhr.send(requestdata); } } }) })).catch((error) => { console.log(error); }); now i'll start write promise embedded fonctionality.
ps : didn't find way mark gaurav mantri answer create mine. ps 2 : i'll put +1 gaurav mantri help... can't :/
Comments
Post a Comment