javascript - Upload properly encoded (base64?) image to SharePoint with AngularJS -
i able upload image file sharepoint, not being recognized image. have tried utilizing following directive based on research states images need base64 encoded when uploaded sharepoint, still uploads file appears corrupt: https://github.com/adonespitogo/angular-base64-upload
i happy use directive, unsure of how pass need sharepoint's rest api.
the original iteration had not use directive, more of straight upload attempt.
what need achieve follows:
1) upload image without being "corrupted", , require base64 encoding/how achieve this?
2) upload images name (not "test.jpg") , have metadata (ex. upload image title or department name belongs to)
iteration 1: no directive here html (please note controller tied page via ng-route):
<div class="col-md-12"> <form> <input type="file" onchange="angular.element(this).scope().fileschanged(this)" data-ng-model="files" multiple> <button data-ng-click="upload()">submit</button> <li data-ng-repeat="file in files">{{file.name}}</li> </form> </div>
here controller:
$scope.fileschanged = function (elm) { $scope.files = elm.files $scope.$apply(); } $scope.upload = function () { var fd = new formdata() angular.foreach($scope.files,function(file){ fd.append('file',file) }) $http.post("/sites/asite/_api/web/lists/getbytitle('images')/rootfolder/files/add(url='test.jpg',overwrite='true')", fd, { transformrequest: angular.identity, headers: { 'content-type':undefined, 'x-requestdigest': $("#__requestdigest").val()} }).success(function (d) { console.log(d); }); }
update: believe issue isolated $http post sharepoint. using directive mentioned above, able output base64, unsure how pass post upload.
iteration 2: using directive here current html using https://github.com/adonespitogo/angular-base64-upload directive:
<form> <input type="file" data-ng-model="files" base-sixty-four-input> <button data-ng-click="upload()">submit</button> </form>
my controller posting corrupted image files sharepoint:
$scope.upload = function () { console.log($scope.files); // output result upload directive $http({ method: 'post', url: "/sites/ens/_api/web/lists/getbytitle('report images')/rootfolder/files/add(url='" + $scope.files.filename +"',overwrite='true')", headers: { 'content-type': false , 'x-requestdigest': $("#__requestdigest").val() }, data: $scope.files, }).success(function (data) { console.log(data); }); }
update 2: using sp.requestexecutor follows creates same result. file upload not rendering. happens images , documents:
iteration 3: using directive , sp.requestexecutor
$scope.upload = function () { var dataurl = 'data:' + $scope.files.filetype + ';' + 'base64,' + $scope.files.base64; var createitem = new sp.requestexecutor("/sites/asite"); createitem.executeasync({ url: "/sites/asite/_api/web/lists/getbytitle('images')/rootfolder/files/add(url='" + $scope.files.filename + "')", method: "post", binarystringrequestbody: true, body: dataurl, success: fsucc, error: ferr, state: "update" }); function fsucc(data) { alert('success'); } function ferr(data) { alert('error\n\n' + data.statustext + "\n\n" + data.responsetext); } }
update 3: using .ajax follows, post image, when using $http, corrupts image.
iteration 3: using .ajax (works)
function uploadfilesync(spweburl , library, filename, file) { var reader = new filereader(); reader.onloadend = function(evt) { if (evt.target.readystate == filereader.done) { var buffer = evt.target.result; var completeurl = spweburl + "/_api/web/lists/getbytitle('"+ library +"')" + "/rootfolder/files/add(url='"+ filename +"',overwrite='true')?" + "@targetlibrary='"+library+"'&@targetfilename='"+ filename +"'"; $.ajax({ url: completeurl, type: "post", data: buffer, async: false, processdata: false, headers: { "accept": "application/json;odata=verbose", "x-requestdigest": $("#__requestdigest").val(), "content-length": buffer.bytelength }, complete: function (data) { //uploaded pic url console.log(data.responsejson.d.serverrelativeurl); $route.reload(); }, error: function (err) { alert('failed'); } }); } }; reader.readasarraybuffer(file); }
iteration 4: using $http (corrupts image)
function uploadfilesync(spweburl , library, filename, file) { var reader = new filereader(); reader.onloadend = function (evt) { if (evt.target.readystate == filereader.done) { var buffer = evt.target.result; var completeurl = spweburl + "/_api/web/lists/getbytitle('" + library + "')" + "/rootfolder/files/add(url='" + filename + "',overwrite='true')?" + "@targetlibrary='" + library + "'&@targetfilename='" + filename + "'"; $http({ url: completeurl, method: "post", data: buffer, processdata: false, headers: { "accept": "application/json;odata=verbose", "x-requestdigest": $("#__requestdigest").val(), "content-length": buffer.bytelength } }).success(function (data) { //uploaded pic url //console.log(data.responsejson.d.serverrelativeurl); $route.reload(); }).error(function (err) { alert(err); }); } }; reader.readasarraybuffer(file); }
yes, must base64 encoding.
following article, fileschanged
function base64 encoding:
$scope.fileschanged = function (input) { if (input.files && input.files[0]) { var reader = new filereader(); reader.onload = function (e) { //sets old image new new image $('#photo-id').attr('src', e.target.result); //create canvas , draw image on client side byte[] equivalent var canvas = document.createelement("canvas"); var imageelement = document.createelement("img"); imageelement.setattribute('src', e.target.result); canvas.width = imageelement.width; canvas.height = imageelement.height; var context = canvas.getcontext("2d"); context.drawimage(imageelement, 0, 0); var base64image = canvas.todataurl("image/jpeg"); //removes data type prefix //and set view model new value $scope.data.photo = base64image.replace(/data:image\/jpeg;base64,/g, ''); } //renders image on page reader.readasdataurl(input.files[0]); } };
my advice change ng-model $scope.files $scope.data.photo avoid problems scope , add id in input tag. (in case id="photo-upload")
so, html upload like:
<input type="file" onchange="angular.element(this).scope().fileschanged(this)" data-ng-model="data.photo" id="photo-upload" multiple>
and representing uploaded pic, in case, can use this:
<img ng-src="data:image/jpeg;base64,{{data.photo}}" id="photo-id"/>
i'm not sure multiple upload, single upload works great me.
hope solve problem sharepoint.
good luck!
Comments
Post a Comment