2015-06-13 16 views
18

Sono in grado di caricare un file immagine in SharePoint, ma non viene riconosciuto come immagine. Ho provato a utilizzare la seguente direttiva basata sulla ricerca che afferma che le immagini devono essere codificate in base64 quando caricate in SharePoint, ma carica ancora un file che sembra essere corrotto: https://github.com/adonespitogo/angular-base64-uploadCarica correttamente l'immagine codificata (base64?) In SharePoint con AngularJS

Sono felice di usare questa direttiva, ma sono insicuro su come passare ciò che ho bisogno in API REST di SharePoint.

L'iterazione originale che avevo non utilizza questa direttiva, ma è più un tentativo di upload diretto.

Che cosa ho bisogno di ottenere è la seguente:

1) caricare con successo un'immagine senza essere "corrotto", e che questo richiede la codifica Base64/come posso raggiungere questo obiettivo?

2) Carica le immagini dal loro nome (non "test.jpg") e hanno alcuni metadati (ex caricare un'immagine con il nome del titolo o il reparto di appartenenza)

Iterazione 1:. No Direttiva Qui è il mio HTML (si prega di notare che il controller è legata alla pagina tramite ng-itinerario):

<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> 

Ecco il mio 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: Credo che il problema sia isolato per il mio post $ http in SharePoint. Usando la direttiva sopra menzionata, sono in grado di emettere la base64, ma non sono sicuro di come passare questo nel mio post per il caricamento.

Iterazione 2: Uso direttiva Qui è il mio attuale HTML usando la direttiva 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> 

mio controller che sta inviando i file immagine danneggiati a 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); 
     }); 
    } 

Aggiornamento 2: L'utilizzo di SP.RequestExecutor come segue crea lo stesso risultato. Un caricamento di file ma non il rendering. Questo accade per immagini e documenti:

Iterazione 3: Utilizzo direttiva e 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: Utilizzando .ajax come segue, che pubblicherà con successo l'immagine, ma quando si utilizza $ http, corrompe l'immagine.

Iterazione 3: Utilizzo .ajax (opere)

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); 
    } 

Iterazione 4: Uso (immagine corrompe) $ http

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); 
} 

risposta

7

Sì, è necessario effettuare la codifica Base64.

A seguito di questa article, il tuo filesChanged sarà funzione per la codifica 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]); 
    } 
}; 

Il mio consiglio è anche quello di cambiare ng-modello da $ scope.files-$ scope.data.Photo a avoid problems with scope e aggiungi un id nel tag di input. (In questo caso id = "photo-upload")

Quindi, il codice HTML per l'upload sarà simile:

<input type="file" onchange="angular.element(this).scope().filesChanged(this)" data-ng-model="data.Photo" id="photo-upload" multiple> 

E per rappresentare il vostro pic caricato, nel tuo caso, è possibile utilizzare questo:

<img ng-src="data:image/jpeg;base64,{{data.Photo}}" id="photo-id"/> 

Non sono sicuro per il caricamento multiplo, ma per il caricamento singolo funziona perfettamente per me.

Spero che questo ti aiuti a risolvere il tuo problema con SharePoint.

Buona fortuna!

+1

Nessuna fortuna. Non riesce con un "Impossibile impostare la proprietà" Foto "di riferimento non definito o nullo" su questa riga: $ scope.data.Photo = base64Image.replace (/ data: image \/jpeg; base64,/g, '') ; – Kode

+1

Nella parte superiore del controller, provare a inizializzare _ $ scope.data_ come oggetto: ** $ scope.data = {} ** – arman1991

+0

Il problema sembra essere con il mio inserimento dei dati. Puoi vedere la mia funzione di caricamento e vedere perché non passa i dati corretti/in che modo inserisco la base64? – Kode