node google files javascript google-drive-sdk

files - Carga reanudable de Google Drive con javascript



google drive json api (2)

Intento subir archivos a Google Drive usando las API de Google, la biblioteca del cliente para JavaScript y el tipo de carga reanudable .

Me autentico y obtengo el URI de carga con éxito, pero me encontré con problemas al enviar los datos reales. Si el archivo contiene solo caracteres ASCII, el archivo se envía correctamente a Drive, pero en el caso de caracteres especiales (åäö) o archivos binarios (como PNG), el archivo se corrompe. Mi suposición sería que en algún lugar del proceso el archivo está codificado para unicode en el lado del cliente.

Si uso "btoa ()" para codificar los datos brutos en base64 y agrego el encabezado "Codificación de contenido: base64" a la solicitud de envío de datos, el archivo se carga bien. Sin embargo, el uso de este método aumenta la sobrecarga del 33%, que es bastante cuando el tamaño de carga planificado de los archivos es de 100 MB a 1 GB.

Aquí hay algunos ejemplos de código:

Obteniendo el URI de carga reanudable:

// Authentication is already done var request = gapi.client.request({ "path": DRIVE_API_PATH, // "/upload/drive/v2/files" "method": "POST", "params": { "uploadType": "resumable" }, "headers": { "X-Upload-Content-Type": self.file.type, //"X-Upload-Content-Length": self.file.size // If this is uncommented, the upload fails because the file size is // different (corrupted file). Manually setting to the corrupted file // size doesn''t give 400 Bad Request. }, "body": { // self.file is the file object from <input type="file"> "title": self.file.name, "mimeType": self.file.type, "Content-Lenght": self.file.size, } });

Envío de todo el archivo de una vez:

// I read the file using FileReader and readAsBinaryString // body is the reader.result (or btoa(reader.result)) // and this code is ran after the file has been read var request = gapi.client.request({ "path": self.resumableUrl, // URI got from previous request "method": "PUT", "headers": { //"Content-Encoding": "base64", // Uploading with base64 works "Content-Type": self.file.type }, "body": body });

¿Me estoy perdiendo de algo? ¿Es posible cargar archivos en flujo binario? Soy nuevo en la carga de archivos en HTML y Javascript y no he encontrado ningún ejemplo utilizando la biblioteca de Google Javascript con carga reanudable. Hay una pregunta similar en SO, sin respuestas.


Los tipos de blobs son un tema candente para las implementaciones de XMLHttpRequest y no son realmente maduros. Te recomendaría que te quedaras con la codificación base64. La versión beta del cliente de JavaScript de Google no admite cargas reanudables porque es muy poco probable que una aplicación del navegador del lado del cliente cargue archivos muy grandes directamente en Google Drive.


Que funciona

Para subir un blob binario, use github / googleapi''s cors-upload-sample o use mi fork principal, UploaderForGoogleDrive , que tomará access_token del cliente gapi por usted.

Aquí hay una fea mezcla de promesas y código de devolución de llamada que funciona para mí. Como requisito previo, gapi , UploaderForGoogleDrive , JSZip deben cargarse mediante etiquetas <script> . El fragmento también omite la inicialización de gapi y los secretos de API, que también son necesarios.

function bigCSV(){ // makes a string for a 300k row CSV file const rows = new Array(300*1000).fill('''').map((v,j)=>{ return [j,2*j,j*j,Math.random(),Math.random()].join('',''); }); return rows.join("/n"); } function bigZip(){ // makes a ZIP file blob, about 8MB const zip = new window.JSZip(); zip.folder("A").file("big.csv", bigCSV()); return zip.generateAsync({type:"blob", compression:"DEFLATE"}); // returns Promise<blob> } function upload2(zipcontent){ ''use strict''; const parent = ''root''; const spaces = ''drive''; const metadata = { name: ''testUpload2H.zip'', mimeType: ''application/zip'', parents: [parent] }; const uploader = new window.UploaderForGoogleDrive({ file: zipcontent, metadata: metadata, params: { spaces, fields: ''id,name,mimeType,md5Checksum,size'' }, onProgress: function(x){ console.log("upload progress:",Math.floor(100*x.loaded/x.total)); }, onComplete: function(x){ if (typeof(x)===''string'') x = JSON.parse(x); // do something with the file metadata in x console.log("upload complete: "); }, onError: function(e){ console.log("upload error: ",e); } }); uploader.upload(); } function uploadZipFile(){ ''use strict''; (bigZip() .then(upload2) ); }

Lo que no funciona

A partir de noviembre de 2017, cargar un blob binario con la llamada gapi.client.request no va a funcionar, debido a un problema donde gapi elimina la carga de PUT

También intenté usar base64 con gapi , que funciona. pero deposita archivos base64, no binarios verdaderos; y la API de recuperación en modo cors, que funcionó a medias, pero produjo errores relacionados con CORS y ocultación de respuestas, al menos para mí.