Uploading image to Azure BlobStorage with Javascript - javascript

I want to select an image file on my HTML5 Webpage with Input type="file" and send it with jQuery or plain JavaScript to my Azure BlobStorage (secured with SAS).
There are some examples how to do this out in the net. I´ve handled till now everything, what I Need: Creating SAS, sending PUT to BlobStorage with SAS and CORS. My Image is created in BlobStorage. BUT: My file on Azure has a length of 0.
Since my code is working so far, that it created an "empty" file in the cloud, my Problem is now, how I can send the right data to it.
Here´s my Submission:
f_UploadSelectedHandler(evt) {
var reader = new FileReader();
reader.onloadend = function (reader_evt) {
// Here are my tries:
var mByteArray = reader_evt.target.result;
//var mByteArray = new Uint8Array(reader_evt.target.result);
//var mFileData = '';
//for (var i = 0; i < mByteArray.byteLength; i++) {
// mFileData += String.fromCharCode(mByteArray[i]);
//}
$.ajax({
url: mSAS_URL,
type: "PUT",
//data: mFileData,
data: mByteArray,
headers: {
"x-ms-blob-type": "BlockBlob",
"x-ms-date": (new Date()).toUTCString(),
"Content-Type": mSelectedFileContentType
},
success: function (data) {
alert("done");
},
error: function (e, y, s) {
alert("error");
}
})
}
reader.readAsArrayBuffer(evt.target.files[0]);
}
If I use var mByteArray = reader_evt.target.result; the uploaded file has a size of 0.
If I use var mByteArray = new Uint8Array(reader_evt.target.result); the uploaded file is corrupted.
If I use var mFileData = ''; for (var i = 0; i < mByteArray.byteLength; i++) { mFileData += String.fromCharCode(mByteArray[i]); } the uploaded file is corrupted.
Every sample I found on the net uses the simplest way:
Init everything with: reader.readAsArrayBuffer(evt.target.files[0]);
Putting in data for ajax: reader_evt.target.result
But so my file is 0. It seems, I have to encode or convert the data from reader_evt.target.result for Azure in some way. Or the reader.readAsArrayBuffer(evt.target.files[0]); is the wrong method. But I´ve tried everything ...
Any ideas?

Got it:
$.ajax({
url: blobSasUrl,
type: "PUT",
data: fileDataAsArrayBuffer,
processData: false,
:
:
The last line was the missing link. I must say to jQuery, to let the data as it is...

Related

How to upload and GET the Items in the SharePoint Document Library from client side using REST API as a HOSTED APP?

Help me with the detailed code, Because am new to this environment. My need is, I need to upload a image into a SharePoint Document library from the client side using REST API and also I want to retrieve the item which is there in the document Library and append it into a page. I trying this one as a SharePoint Hosted App.
I'm Using SharePoint Online;
We can use REST API an jQuery in SharePoint hosted add-in to achieve it, the following code for your reference.
'use strict';
var appWebUrl, hostWebUrl;
jQuery(document).ready(function () {
// Check for FileReader API (HTML5) support.
if (!window.FileReader) {
alert('This browser does not support the FileReader API.');
}
// Get the add-in web and host web URLs.
appWebUrl = decodeURIComponent(getQueryStringParameter("SPAppWebUrl"));
hostWebUrl = decodeURIComponent(getQueryStringParameter("SPHostUrl"));
});
// Upload the file.
// You can upload files up to 2 GB with the REST API.
function uploadFile() {
// Define the folder path for this example.
var serverRelativeUrlToFolder = '/shared documents';
// Get test values from the file input and text input page controls.
// The display name must be unique every time you run the example.
var fileInput = jQuery('#getFile');
var newName = jQuery('#displayName').val();
// Initiate method calls using jQuery promises.
// Get the local file as an array buffer.
var getFile = getFileBuffer();
getFile.done(function (arrayBuffer) {
// Add the file to the SharePoint folder.
var addFile = addFileToFolder(arrayBuffer);
addFile.done(function (file, status, xhr) {
// Get the list item that corresponds to the uploaded file.
var getItem = getListItem(file.d.ListItemAllFields.__deferred.uri);
getItem.done(function (listItem, status, xhr) {
// Change the display name and title of the list item.
var changeItem = updateListItem(listItem.d.__metadata);
changeItem.done(function (data, status, xhr) {
alert('file uploaded and updated');
});
changeItem.fail(onError);
});
getItem.fail(onError);
});
addFile.fail(onError);
});
getFile.fail(onError);
// Get the local file as an array buffer.
function getFileBuffer() {
var deferred = jQuery.Deferred();
var reader = new FileReader();
reader.onloadend = function (e) {
deferred.resolve(e.target.result);
}
reader.onerror = function (e) {
deferred.reject(e.target.error);
}
reader.readAsArrayBuffer(fileInput[0].files[0]);
return deferred.promise();
}
// Add the file to the file collection in the Shared Documents folder.
function addFileToFolder(arrayBuffer) {
// Get the file name from the file input control on the page.
var parts = fileInput[0].value.split('\\');
var fileName = parts[parts.length - 1];
// Construct the endpoint.
var fileCollectionEndpoint = String.format(
"{0}/_api/sp.appcontextsite(#target)/web/getfolderbyserverrelativeurl('{1}')/files" +
"/add(overwrite=true, url='{2}')?#target='{3}'",
appWebUrl, serverRelativeUrlToFolder, fileName, hostWebUrl);
// Send the request and return the response.
// This call returns the SharePoint file.
return jQuery.ajax({
url: fileCollectionEndpoint,
type: "POST",
data: arrayBuffer,
processData: false,
headers: {
"accept": "application/json;odata=verbose",
"X-RequestDigest": jQuery("#__REQUESTDIGEST").val(),
"content-length": arrayBuffer.byteLength
}
});
}
// Get the list item that corresponds to the file by calling the file's ListItemAllFields property.
function getListItem(fileListItemUri) {
// Construct the endpoint.
// The list item URI uses the host web, but the cross-domain call is sent to the
// add-in web and specifies the host web as the context site.
fileListItemUri = fileListItemUri.replace(hostWebUrl, '{0}');
fileListItemUri = fileListItemUri.replace('_api/Web', '_api/sp.appcontextsite(#target)/web');
var listItemAllFieldsEndpoint = String.format(fileListItemUri + "?#target='{1}'",
appWebUrl, hostWebUrl);
// Send the request and return the response.
return jQuery.ajax({
url: listItemAllFieldsEndpoint,
type: "GET",
headers: { "accept": "application/json;odata=verbose" }
});
}
// Change the display name and title of the list item.
function updateListItem(itemMetadata) {
// Construct the endpoint.
// Specify the host web as the context site.
var listItemUri = itemMetadata.uri.replace('_api/Web', '_api/sp.appcontextsite(#target)/web');
var listItemEndpoint = String.format(listItemUri + "?#target='{0}'", hostWebUrl);
// Define the list item changes. Use the FileLeafRef property to change the display name.
// For simplicity, also use the name as the title.
// The example gets the list item type from the item's metadata, but you can also get it from the
// ListItemEntityTypeFullName property of the list.
var body = String.format("{{'__metadata':{{'type':'{0}'}},'FileLeafRef':'{1}','Title':'{2}'}}",
itemMetadata.type, newName, newName);
// Send the request and return the promise.
// This call does not return response content from the server.
return jQuery.ajax({
url: listItemEndpoint,
type: "POST",
data: body,
headers: {
"X-RequestDigest": jQuery("#__REQUESTDIGEST").val(),
"content-type": "application/json;odata=verbose",
"content-length": body.length,
"IF-MATCH": itemMetadata.etag,
"X-HTTP-Method": "MERGE"
}
});
}
}
// Display error messages.
function onError(error) {
alert(error.responseText);
}
// Get parameters from the query string.
// For production purposes you may want to use a library to handle the query string.
function getQueryStringParameter(paramToRetrieve) {
var params = document.URL.split("?")[1].split("&");
for (var i = 0; i < params.length; i = i + 1) {
var singleParam = params[i].split("=");
if (singleParam[0] == paramToRetrieve) return singleParam[1];
}
}
Refer to: Upload a file by using the REST API and jQuery

How to post file with ajax?

Trying to save a file to a db. I am using formData via javascript to append the file and adding this as a post object via ajax. for some reason nothing gets sent.
What am I doing wrong?
HTML
<input type="file" style="display: none;" class="btn btn-primary uploadFile">
script:
$(".saveImage")
.on("click",
function() {
var files = $(".uploadFile");
var data = new FormData();
data = $.OverWatch.worker.uploadFileHandler.addUploadFiles(files, data);
$.OverWatch.worker.postUserData("/Administration/AddUserImage", data, function () {
alert("done");
});
});
Functions above look like:
addUploadFiles: function (files, data) {
$.each(files, function (i, v) {
var file = $(this).data("files");
data.append("file", file);
});
return data;
}
postUserData:
postUserData: function(url, data, callback) {
$.LoadingOverlay("show");
$.ajax({
url: url,
type: 'POST',
data: data,
cache: false,
processData: false,
contentType: false,
dataType: "HTML",
success: function(data) {
if (callback) {
callback(data);
$.LoadingOverlay("hide");
}
},
error: function(event, jqxhr, settings, thrownError) {
//$.helpers.errorHandler($("#fileDialogErrors"), event.responseText);
var h;
$.LoadingOverlay("hide");
}
});
},
backend:
public ActionResult AddUserImage()
{
if (Request.Files.Count != 0)
{
//save
}
return null;
}
edit:
var files = $(".uploadFile");
returns:
Your var file = $(this).data("files"); line of code would be returning undefined (unless you have some other javascript adding a data value, but you cannot add files to data so it in any case it would not be returning a file).
Change your loop to
$.each(files, function (i, v) {
for (i = 0; i < v.files.length; i++) {
var file = v.files[i];
data.append("file", file);
}
});
However, you can simplify this by using var data = new FormData($('form').get(0)); which will serialize all you form controls including file inputs to FormData (refer how to append whole set of model to formdata and obtain it in MVC for more information).
I also recommend you change your method signature to
public ActionResult AddUserImage(IEnumerable<HttpPostedFileBase> files)
and let the DefaultModelBinder do its magic.
you can directly get file from controller when called using Request.Files
//(Request) HttpRequestBase object for the current HTTP request
if (Request.Files.Count > 0)//// Is image is uplaod by browse button
{
var inputStream = Request.Files[0].InputStream;
using (var binaryReader = new BinaryReader(inputStream))
{
var ImageBytes = binaryReader .ReadBytes(Request.Files[0].ContentLength); // same as you can get multiple file also
}
var fileExtension = Path.GetExtension(Request.Files[0].FileName);
}
thanks.
I haven't done it with jQuery but just learned how to do it myself yesterday using plain old javascript... the following worked for me. If you want to stick with jquery maybe you can translate the functions to what you need:
var formElement = document.querySelector("form");
var payload = new FormData(formElement);
function onStateChange(ev) {
// Check if the request is finished
if (ev.target.readyState == 4) {
editor.busy(false);
if (ev.target.status == '200') {
// Save was successful, notify the user with a flash
} else {
// Save failed, notify the user with a flash
}
}
};
xhr = new XMLHttpRequest();
xhr.addEventListener('readystatechange', onStateChange);
xhr.open('POST', '/posts');
xhr.send(payload);
Maybe see if using the above code works for you (it just targets a form that you have on the same page), and then you can troubleshoot whether it's your script that's the problem or a backend / communication problem.

How to POST both normal JSON data and multiple files to Spring MVC controller through single Ajax request?

I am trying to create a form page consisting of both normal HTML form fields like text boxes, dropdown lists, checkboxes, etc. along with multiple HTML file elements.
Is it possible to POST both the normal JSON data that is built from the normal HTML elements and also the multiple files that are selected to the Spring MVC controller through a single Ajax request?
Is it possible to append stringify-ed JSON object to JavaScript's FormData object?
I'm trying to create a form as shown in the image below:-
Following is the JavaScript code that I'm trying onclick of submit button :-
function submitMyForm() {
function MyFormData(arrOfCityVisitData,arrOfUploadDocsData) {
this.citiesVisitedData = arrOfCityVisitData;
this.uploadDocsData = arrOfUploadDocsData;
}
function CityVisitData(intStateID,intCityID,strVisitDate,strVisitRemarks,intRecID) {
this.stateID = intStateID;
this.cityID = intCityID;
this.visiteDate = strVisitDate;
this.visitRemarks = strVisitRemarks;
this.recID = intRecID;
}
function UploadDocsData(strFileName,strUploadDocsRemarks,intRecID) {
this.fileName = strFileName;
this.uploadDocRemarks = strUploadDocsRemarks;
this.recID = intRecID;
}
var arrOfCityVisitData = new Array();
var intVisitDataTblRowCount=document.getElementById("citiesVisitedByDateTbl").rows.length-1; // 1 static header row
for(var i=0;i<intVisitDataTblRowCount;i++) {
var cityVisitData = new CityVisitData(parseInt(document.myForm.visitedState[i].value,10),
parseInt(document.myForm.visitedCity[i].value,10),
document.myForm.visitDate[i].value,
document.myForm.visitRemarks[i].value,
(document.myForm.visitRecID[i].value!=="") ? parseInt(document.myForm.visitRecID[i].value,10) : -1);
arrOfCityVisitData[i]=cityVisitData;
}
var arrOfUploadDocsData = new Array();
var intUploadDocsTblRowCount=document.getElementById("uploadDocumentsTbl").rows.length-1; // 1 static header row
for(var i=0;i<intUploadDocsTblRowCount;i++) {
var uploadDocData = new UploadDocsData(document.myForm.uploadDocsFile[i].value,
document.myForm.uploadDocsRemarks[i].value,
(document.myForm.uploadDocsRecID[i].value!=="") ? parseInt(document.myForm.uploadDocsRecID[i].value,10) : -1);
arrOfUploadDocsData[i]=uploadDocData;
}
var formData = new FormData();
for (var i = 0, len = $('input[type=file]').length; i < len; i++) {
if($('input[type=file]')[i].files[0]) {
formData.append('file'+i, $('input[type=file]')[i].files[0]);
}
}
alert(JSON.stringify(new MyFormData(arrOfCityVisitData,arrOfUploadDocsData)));
formData.append('myFormData',JSON.stringify(new MyFormData(arrOfCityVisitData,arrOfUploadDocsData)));
console.log("form data " + JSON.stringify(formData));
$.ajax({
url: 'http://localhost:8080/springcrud/ajax/processFormData.do',
data: formData,
headers: {
'Accept': 'application/json',
'Content-Type': 'application/json'
},
//enctype: 'multipart/form-data',
cache: false,
contentType: false,
processData: false,
type: 'POST',
success: function (data) {
console.log(data);
}
});}
And following is the Spring MVC controller class's request handler method :-
#RequestMapping(value="/processFormData.do",method=RequestMethod.POST,headers = {"Content-type=application/json"})
#ResponseBody
public String processFormData(#RequestBody MyFormData myFormData) {
System.out.println(((myFormData.getCitiesVisitedData()).get(0)).getVisiteDate());
return "ajaxTrial";
}
And currently this code is throwing 415 (Unsupported Media Type) error in the browser. What changes are to be done to the above code so that files can be uploaded along with normal form data through jQuery ajax request?

Add data to Jquery.Ajax post when uploading file?

I'm building a drag n drop upload feature for my MVC 4 webapp using this tutorial:
http://hayageek.com/drag-and-drop-file-upload-jquery/
However, besides the file, I also want to send info regarding where it came from (some ID for instance) and the type (domain-type).
In my ajax post below, how can I add extra data and read it server side?
In the tutorial code a line with 'extra data' is seen, however it is not actually implemented.
function sendFileToServer(formData, status) {
var uploadURL = '/home/upload';
var extraData = {}; //Extra Data.
var jqXHR = $.ajax({
xhr: function() {
var xhrobj = $.ajaxSettings.xhr();
if (xhrobj.upload) {
xhrobj.upload.addEventListener('progress', function(event) {
var percent = 0;
var position = event.loaded || event.position;
var total = event.total;
if (event.lengthComputable) {
percent = Math.ceil(position / total * 100);
}
//Set progress
status.setProgress(percent);
}, false);
}
return xhrobj;
},
url: uploadURL,
type: "POST",
contentType: false,
processData: false,
cache: false,
data: formData,
success: function (data) {
status.setProgress(100);
//$("#status1").append("File upload Done<br>");
}
});
status.setAbort(jqXHR);
}
Thanks!
To pass additional data to your controller via Ajax Upload File, it just needs to append your additional data to formData in your Ajax call function(sendFileToServer). i.e. you'd like to pass an upload target folder:
formData.append('targetFolder', 'User File Upload Folder');
and in your action get access to your additional parameter:
[HttpPost]
public ActionResult Upload(HttpPostedFileBase file, string targetFolder)
I fixed the problem by creating a workaround, I'm passing the extra data (id etc) via the URL which I receive as parameters on the controller method.

upload photo on facebook using javascript

I am trying to upload photo on facebook using javascript. I was able to do status update doing javascript but still struggling with how to upload photo. Can someone please tell me how to code this in Javascript?
The correct code would be:
var params = {};
params.url = 'https://myserver.com/myimage.jpg';
FB.api('/me/photos', 'post', params, function(response) {
if (!response || response.error) {
//error
} else {
picid = response.id;
}
});
Keep in mind that the photo has to be on your server, so you need a server script for the upload. the "url" parameter is the absolute url of your uploaded image file.
More information: https://developers.facebook.com/docs/reference/api/user/ (see Photos/Create)
Keep in mind that the "message" parameter has to be 100% user generated according to the Facebook terms. You also can´t post to a friend wall of the logged in user, that functionality is deprecated and does not work anymore.
I hope this will be useful. By doing photo upload to FB only with the help of javascript you can use the following method. Required thing here are imageData(which is base64 format of image) and the mime type.
try{
blob = dataURItoBlob(imageData,mimeType);
}catch(e){console.log(e);}
var fd = new FormData();
fd.append("access_token",accessToken);
fd.append("source", blob);fd.append("message","Kiss");
try{
$.ajax({
url:"https://graph.facebook.com/" + <<userID received on getting user details>> + "/photos?access_token=" + <<user accessToken>>,
type:"POST"
data:fd,
processData:false,
contentType:false,
cache:false,
success:function(data){
console.log("success " + data);
},
error:function(shr,status,data){
console.log("error " + data + " Status " + shr.status);
},
complete:function(){
console.log("Ajax Complete");
}
});
}catch(e){console.log(e);}
function dataURItoBlob(dataURI,mime) {
// convert base64 to raw binary data held in a string
// doesn't handle URLEncoded DataURIs
var byteString = window.atob(dataURI);
// separate out the mime component
// write the bytes of the string to an ArrayBuffer
//var ab = new ArrayBuffer(byteString.length);
var ia = new Uint8Array(byteString.length);
for (var i = 0; i < byteString.length; i++) {
ia[i] = byteString.charCodeAt(i);
}
// write the ArrayBuffer to a blob, and you're done
var blob = new Blob([ia], { type: mime });
return blob;
}
Here is an example code :
var imgURL = 'URL de la photo a uploader';
FB.api('/ALBUM_ID/photos', 'post', {
message: ' Ma photo',
url: imgURL,
}, function (response) {
});

Categories