2017-09-11 2 views
13

Ich versuche, this Leitfaden für wiederaufladbare Uploads auf Google Drive über Google Api zu folgen.Wie lade ich Dateien mit Gapi und fortsetzbaren Uploads auf Google Drive hoch?

Dies ist mein Code, Sie können sehen, dass es zwei Anfragen an den Guide stellt, der erste Teil erstellt die Metadaten und dann verwenden wir den Speicherort für den Upload der Dateien mit der Sitzung, die bei der ersten Anfrage erstellt wurde.

 const file = new File(['Hello, world!'], 'hello world.txt', { type: 'text/plain;charset=utf-8' }); 
     const contentType = file.type || 'application/octet-stream'; 

     const reqMetadata = gapi.client.request({ 
      'path': 'upload/drive/v3/files', 
      'method': 'POST', 
      'params': { 'uploadType': 'resumable' }, 
      'headers': { 
       'X-Upload-Content-Type': file.type, 
       'X-Upload-Content-Length': file.size, 
       'Content-Type': 'application/json; charset=UTF-8' 
      }, 
      'body': { 
       'name': file.name, 
       'mimeType': contentType, 
       'Content-Type': contentType, 
       'Content-Length': file.size 
      } 
     }); 

     reqMetadata.execute((respMetadata, rawRespMetadata: any) => { 
      const locationUrl = JSON.parse(rawRespMetadata).gapiRequest.data.headers.location; 

      const reader = new FileReader(); 

      reader.onload = (e) => { 
       const reqFile = gapi.client.request({ 
        'path': locationUrl, 
        'method': 'PUT', 
        'headers': { 
         'Content-Type': file.type, 
         'Content-Length': file.size 
        }, 
        'body': reader.result 
       }); 

       reqFile.execute(respFile => { 
        console.log(respFile); 
       }); 
      }; 

      reader.readAsArrayBuffer(file); 
     }); 

Was ist das Problem?

Nun, scheint, dass die Google-API-Bibliothek nicht die Datei/Byte-Array auf ihre gapi.client.request als Körper nicht mag und sie Kürzen es weg see image

Was ist der richtige Weg, um die Datei zu übergeben? Ich habe beide Körper versucht: Datei und Körper: reader.result aber das gleiche Ergebnis

PS: Gapi ist bereits vollständig authentifiziert & mit Auth2 initialisiert, ich bin in der Lage, Dateien/Verzeichnis zu erstellen.

EDIT 1:

gapi Bibliothek gerade ist jsoing die FileArray, deshalb ist die JSON-Funktion es zu einem leeren Objekt ändert, keine Möglichkeit, es .. funktioniert etwas fehlen muss.

EDIT 2:

Ich habe es ohne die GAPI zu arbeiten, es lädt die Datei korrekt, aber ich habe einige Probleme mit der CORS

  reader.onload = (e) => {      

       const authHeader = `Bearer ${this.auth.currentUser.get().getAuthResponse().access_token}`; 
       const headers = new Headers({ 
        'Authorization': authHeader, 
        'Content-Type': file.type 
       }); 
       const options = new RequestOptions({ headers }); 
       const url = locationUrl; 

       this.http.put(url, reader.result, options).subscribe(res => { 
        observer.next(res); 
       }, (err) => { 
        observer.next({}); 
       }); 
      }; 

      reader.readAsArrayBuffer(file); 

Wenn jemand einige Hinweise hat ..

+0

Welche GAPI-Version verwenden Sie? Außerdem scheint das GAPI Sreams zum Hochladen von Ifles in NodeJS zu verwenden. Sie könnten versuchen mit [dies] (https://github.com/dominictarr/browser-stream) –

+0

Sollte die neueste Version sein, wo haben Sie Dokumentation über die Verwendung von Streams (Sockets) gefunden? –

+0

[Hier] (https://developers.google.com/drive/v3/web/manage-uploads), sehen Sie sich die NodeJS-Beispiele an. –

Antwort

1

Sie müssen XMLHttpRequest verwenden, um eine übergreifende HTTP-Anforderung zu erstellen. Der gapi-Client unterstützt XMLHttpRequest nicht. (but there is this pull request that's been open for a while) Auch wenn Sie die Datei binäre Daten nicht in der ursprünglichen Anforderung senden, müssen Sie XMLHttpRequest sowohl für die Initiale als auch für die Anforderung verwenden, bei der die Datei hochgeladen wird, damit die zurückgegebene Standort-URL den entsprechenden Antwort-Header bereitstellt. Allow-Origin: YOUR_URL) und erfüllen die CORS-Anforderungen.

Hier ist eine große tutorial about CORS and XMLHttpRequest, die bei der Konvertierung Ihrer Anforderungen nützlich sein kann.

Sie können die auf der Seite, mit der Sie verlinkt haben, beschriebenen Anforderungsinformationen verwenden. This example shows the request info, bietet jedoch keine Informationen zum Abrufen des Authentifizierungs-Token. But this example does!

konnte ich die Datei mit dem folgenden Code erfolgreich laden:

const file = new File(['Hello, world!'], 'hello world.txt', { type: 'text/plain;charset=utf-8' }); 
const contentType = file.type || 'application/octet-stream'; 
const user = gapi.auth2.getAuthInstance().currentUser.get(); 
const oauthToken = user.getAuthResponse().access_token; 
const initResumable = new XMLHttpRequest(); 
initResumable.open('POST', 'https://www.googleapis.com/upload/drive/v3/files?uploadType=resumable', true); 
initResumable.setRequestHeader('Authorization', 'Bearer ' + oauthToken); 
initResumable.setRequestHeader('Content-Type', 'application/json'); 
initResumable.setRequestHeader('X-Upload-Content-Length', file.size); 
initResumable.setRequestHeader('X-Upload-Content-Type', contentType); 
initResumable.onreadystatechange = function() { 
    if(initResumable.readyState === XMLHttpRequest.DONE && initResumable.status === 200) { 
    const locationUrl = initResumable.getResponseHeader('Location'); 
    const reader = new FileReader(); 
    reader.onload = (e) => { 
     const uploadResumable = new XMLHttpRequest(); 
     uploadResumable.open('PUT', locationUrl, true); 
     uploadResumable.setRequestHeader('Content-Type', contentType); 
     uploadResumable.setRequestHeader('X-Upload-Content-Type', contentType); 
     uploadResumable.onreadystatechange = function() { 
     if(uploadResumable.readyState === XMLHttpRequest.DONE && uploadResumable.status === 200) { 
      console.log(uploadResumable.response); 
     } 
     }; 
     uploadResumable.send(reader.result); 
    }; 
    reader.readAsArrayBuffer(file); 
    } 
}; 

// You need to stringify the request body containing any file metadata 

initResumable.send(JSON.stringify({ 
    'name': file.name, 
    'mimeType': contentType, 
    'Content-Type': contentType, 
    'Content-Length': file.size 
})); 

Aber es ist ein robuster Repo mit all dies hier für den Umgang: https://github.com/googledrive/cors-upload-sample

+0

Danke Mann, Sie verdienen die Prämie. Ich habe das selbe getan wie du, aber der eckige $ http Service am Ende hat mir einen CORS Fehler gegeben. Wahrscheinlich habe ich einen HTTP-Header vermasselt und der Laufwerksrest weigerte sich, Dateien hochzuladen. –

+0

Im Folgenden wurde eine zusätzliche Antwort mit dem Angular-HTTP-Dienst anstelle von einfacher xhr hinzugefügt –

0

die BMcV Lösung übersetzt Dies wird zum eckigen http-Dienst.

const contentType = file.type || 'application/octet-stream'; 
const baseRoot = gapi['config'].get('googleapis.config').root; 

const reader = new FileReader(); 

reader.onload = (e) => { 

    const authHeader = `Bearer ${this.auth.currentUser.get().getAuthResponse().access_token}`; 

    const metadataHeaders = { 
     'Authorization': authHeader, 
     'Content-Type': 'application/json', 
     'X-Upload-Content-Length': file.size, 
     'X-Upload-Content-Type': contentType 
    }; 
    const metadataOptions = new RequestOptions({ headers: new Headers(metadataHeaders) }); 

    const url = `${baseRoot}/upload/drive/v3/files?uploadType=resumable`; 

    const metadata = { 
     'name': file.name, 
     'mimeType': contentType, 
     'Content-Type': contentType, 
     'Content-Length': file.size 
    }; 

    this.http.post(url, metadata, metadataOptions).subscribe(metadataRes => { 

     const locationUrl = metadataRes.headers.get('Location'); 

     const uploadHeaders = { 
      'Content-Type': contentType, 
      'X-Upload-Content-Type': contentType 
     }; 
     const uploadOptions = new RequestOptions({ headers: new Headers(uploadHeaders) }); 

     this.http.put(locationUrl, reader.result, uploadOptions).subscribe(uploadRes => { 
      console.log(uploadRes.json()); 
     }); 
    }, (err) => { 
     console.error(err); 
    }); 
}; 
reader.readAsArrayBuffer(file); 
Verwandte Themen