javascript - img - Cargue la imagen correctamente codificada(base64?) A SharePoint con AngularJS
ng src image base64 (1)
Puedo cargar un archivo de imagen a SharePoint, pero no se reconoce como una imagen. He intentado utilizar la siguiente directiva basada en investigaciones que indican que las imágenes deben estar codificadas en base64 cuando se cargan en SharePoint, pero aún así se carga un archivo que parece estar dañado: https://github.com/adonespitogo/angular-base64-upload
Estoy feliz de usar esta directiva, pero no estoy seguro de cómo pasar lo que necesito a la API REST de SharePoint.
La iteración original que tenía no usa esta directiva, pero es más un intento de carga directa.
Lo que necesito lograr es lo siguiente:
1) Subir con éxito una imagen sin que esté "dañada", ¿y esto requiere codificación base64? ¿Cómo puedo lograrlo?
2) Cargar imágenes por su nombre (no "test.jpg") y tener algunos metadatos (por ejemplo, cargar una imagen con el título o el nombre del departamento al que pertenece)
Iteración 1: Sin directiva Aquí está mi HTML (tenga en cuenta que el controlador está vinculado a la página a través de 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>
Aquí está mi controlador:
$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);
});
}
ACTUALIZACIÓN: Creo que el problema está aislado en mi publicación $ http en SharePoint. Al usar la directiva mencionada anteriormente, puedo generar la base64, pero no estoy seguro de cómo pasar esto a mi publicación para subir.
Iteración 2: uso de la directiva Este es mi código HTML actual mediante la directiva https://github.com/adonespitogo/angular-base64-upload :
<form>
<input type="file" data-ng-model="files" base-sixty-four-input>
<button data-ng-click="upload()">Submit</button>
</form>
Mi controlador que está publicando los archivos de imagen dañados en SharePoint:
$scope.upload = function () {
console.log($scope.files); // Output result from 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);
});
}
Actualización 2: Usar SP.RequestExecutor de la siguiente manera crea el mismo resultado. Un archivo cargado pero no renderizado. Esto sucede para imágenes y documentos:
Iteración 3: Uso de la directiva y 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);
}
}
Actualización 3: al usar .ajax de la siguiente manera, se publicará con éxito la imagen, pero cuando se usa $ http, la imagen se corrompe.
Iteración 3: Usar .Ajax (funciona)
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);
}
Iteración 4: Usar $ http (corrompe la imagen)
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);
}
Sí, debes hacer la codificación base64.
Siguiendo este article , su filesChanged
será función para la codificación base64:
$scope.filesChanged = function (input) {
if (input.files && input.files[0]) {
var reader = new FileReader();
reader.onload = function (e) {
//Sets the Old Image to new New Image
$(''#photo-id'').attr(''src'', e.target.result);
//Create a canvas and draw image on Client Side to get the 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 the Data Type Prefix
//And set the view model to the new value
$scope.data.Photo = base64Image.replace(/data:image//jpeg;base64,/g, '''');
}
//Renders Image on Page
reader.readAsDataURL(input.files[0]);
}
};
Mi consejo para usted también es cambiar el modelo ng de $ scope.files a $ scope.data.Photo para evitar problemas con el alcance y agregar una identificación en su etiqueta de entrada. (en este caso id = "foto-subir")
Por lo tanto, su HTML para subir se verá como:
<input type="file" onchange="angular.element(this).scope().filesChanged(this)" data-ng-model="data.Photo" id="photo-upload" multiple>
Y para representar su foto cargada, en su caso, puede usar esto:
<img ng-src="data:image/jpeg;base64,{{data.Photo}}" id="photo-id"/>
No estoy seguro de la carga múltiple, pero para la carga individual funciona muy bien para mí.
Espero que esto te ayude a resolver tu problema con SharePoint.
¡Buena suerte!