2015-03-26 63 views
5

Sto provando a download a File da unità google utilizzando API Google SDK utilizzando node.js.Impossibile scaricare il file da Google Drive utilizzando API - node.js

Ma io sono in grado di scrivere/salvare il file a lato server - Node.JS

Codice: -

var GoogleTokenProvider = require("refresh-token").GoogleTokenProvider, 
    async = require('async'), 
    fs = require("fs"), 
    request = require('request'), 
    _accessToken; 

var _XMLHttpRequest = require("xmlhttprequest").XMLHttpRequest; 
var https = require('https'); 

const CLIENT_ID = ""; 
const CLIENT_SECRET = ""; 
const REFRESH_TOKEN = ''; 
const ENDPOINT_OF_GDRIVE = 'https://www.googleapis.com/drive/v2'; 

async.waterfall([ 
     //----------------------------- 
     // Obtain a new access token 
     //----------------------------- 
     function(callback) { 
      var tokenProvider = new GoogleTokenProvider({ 
       'refresh_token': REFRESH_TOKEN, 
       'client_id': CLIENT_ID, 
       'client_secret': CLIENT_SECRET 
      }); 
      tokenProvider.getToken(callback); 
     }, 

     //-------------------------------------------- 
     // Retrieve the children in a specified folder 
     // 
     // ref: https://developers.google.com/drive/v2/reference/files/children/list 
     //------------------------------------------- 
     function(accessToken, callback) { 
      _accessToken = accessToken; 
      request.get({ 
       'url': ENDPOINT_OF_GDRIVE + '/files?' + "q='root' in parents and (mimeType = 'application/vnd.openxmlformats-officedocument.wordprocessingml.document')", 
       'qs': { 
        'access_token': accessToken 
       } 
      }, callback); 
     }, 

     //---------------------------- 
     // Parse the response 
     //---------------------------- 
     function(response, body, callback) { 
      var list = JSON.parse(body); 
      if (list.error) { 
       return callback(list.error); 
      } 
      callback(null, list.items[0]); 
     }, 

     //------------------------------------------- 
     // Get the file information of the children. 
     // 
     // ref: https://developers.google.com/drive/v2/reference/files/get 
     //------------------------------------------- 
     function(children, callback) { 

      var xhr = new _XMLHttpRequest(); 
      xhr.open('GET', children.downloadUrl); 
      xhr.setRequestHeader('Authorization', 'Bearer ' + _accessToken); 
      xhr.onload = function() { 
       console.log("xhr.responseText", xhr.responseText) 
       fs.writeFile("download.docx", xhr.responseText) 
       callback(xhr.responseText); 
      }; 
      xhr.onerror = function() { 
       callback(null); 
      }; 
      xhr.send(); 
     } 
    ], 
    function(err, results) { 
     if (!err) { 
      console.log(results); 
     } 
    }); 

sto ottenendo questo in console: - Contenuto XHR .responseText è qualcosa del genere

��▬h��↕E6M��~��3�3∟�9�� � �►��/2�:���♂�4��]�♀I�R���► 
$SB6Q���c↔��H�=;+ 
���►q�3Tdכ��@!T��hEl_�|�I�↨��h(�^:▬�[h̓D♠��f���♠*���ݾ��M→ 
�1⌂♦"N�↑�o�]�7U$��A6����♠�W��k`�f▬♫��K�Z�^‼�0{<Z�▼�]F����� 

          ���J♥A♀��♣�a�}7� 
"���H�w"�♥���☺w♫̤ھ�� �P�^����O֛���;�<♠�aYՠ؛`G�kxm��PY�[��g 
Gΰino�/<���<�1��ⳆA$>"f3��\�ȾT��∟I S�������W♥����Y 

Per favore aiutatemi a sapere a è il formato dei dati che sto ottenendo da Drive Api e scrivere in quale formato in modo tale che ho ottenuto una completa .docx file di

Modifica

Sono aperto a utilizzare un metodo diverso da xmlRichiesta se mi aiuta a scaricare il file (.docx).

+1

La tua priorità principale dovrebbe essere capire come recuperare i dati come Buffer: non appena i dati binari vengono convertiti in String, i dati verranno danneggiati. Utilizzando il modulo Request.js, è necessario impostare la codifica: null nelle opzioni della richiesta. Ma con xhr, non sono sicuro. –

+0

Cosa ti aspettavi dall'uscita? downloadUrl è usato solo per file non di Google. Se si tratta di un documento Google, utilizzerai uno dei link di esportazione. – pinoyyid

+1

@pinoyyid, qualunque sia l'output, quello che voglio è scrivere/salvare/scaricare quei dati nel formato corretto, nel mio caso è un file .docx e dopo averlo scaricato sul server, devo editare quel file .docx –

risposta

10

node-XMLHttpRequest, a quanto pare, non supporta i download binari - vedere this issue. Quello che stai vedendo è il contenuto binario del file convertito in String che, in JavaScript, è un processo irreversibile e distruttivo per i dati binari (il che significa che non puoi convertire la stringa in buffer e ottenere gli stessi dati dei contenuti originali).

Utilizzando request, è possibile scaricare un file binario in questo modo:

var request = require('request') 
    , fs = require('fs') 

request.get(
    { url: 'your-file-url' 
    , encoding: null // Force Request to return the data as Buffer 
    , headers: 
    { Authorization: 'Bearer ' + accessTokenHere 
    } 
    } 
, function done (err, res) { 
    // If all is well, the file will be at res.body (buffer) 
    fs.writeFile('./myfile.docx', res.body, function (err) { 
     // Handle err somehow 
     // Do other work necessary to finish the request 
    }) 
    } 
) 

Nota: Questo tamponare l'intero file in memoria prima di poter essere salvato su disco. Per i file di piccole dimensioni, questo va bene, ma per i file più grandi, si potrebbe voler esaminare l'implementazione come download in streaming. This SO question già risponde che, ti consiglio di dare un'occhiata.

Ulteriori informazioni su come autorizzare le vostre richieste sono disponibili su Google Developers docs.

+0

Ho provato con Request, quindi ricevo il buffer vuoto. –

+0

Bene, cosa c'è in "err"? Controlla anche 'res.statusCode', non dovrebbe essere nell'intervallo 4xx o 5xx. Spostare preferibilmente entrambi gli oggetti su console e ispezionare attentamente la risposta. –

+0

ricevendo 401 e deve essere perché non ho passato accessToken. Nella richiesta dove posso aggiungere accesstoken? –

2

completo esempio di lavoro: Scaricare file da Google Drive - API Node.js

var GoogleTokenProvider = require("refresh-token").GoogleTokenProvider, 
    async = require('async'), 
    fs = require("fs"), 
    request = require('request'), 
    _accessToken; 

const CLIENT_ID = ""; 
const CLIENT_SECRET = ""; 
const REFRESH_TOKEN = ''; 
const ENDPOINT_OF_GDRIVE = 'https://www.googleapis.com/drive/v2'; 

async.waterfall([ 
     //----------------------------- 
     // Obtain a new access token 
     //----------------------------- 
     function(callback) { 
      var tokenProvider = new GoogleTokenProvider({ 
       'refresh_token': REFRESH_TOKEN, 
       'client_id': CLIENT_ID, 
       'client_secret': CLIENT_SECRET 
      }); 
      tokenProvider.getToken(callback); 
     }, 

     //-------------------------------------------- 
     // Retrieve the children in a specified folder 
     // 
     // ref: https://developers.google.com/drive/v2/reference/files/children/list 
     //------------------------------------------- 
     function(accessToken, callback) { 
      _accessToken = accessToken; 
      request.get({ 
       'url': ENDPOINT_OF_GDRIVE + '/files?' + "q='root' in parents and (mimeType = 'application/vnd.openxmlformats-officedocument.wordprocessingml.document')", 
       'qs': { 
        'access_token': accessToken 
       } 
      }, callback); 
     }, 

     //---------------------------- 
     // Parse the response 
     //---------------------------- 
     function(response, body, callback) { 
      var list = JSON.parse(body); 
      if (list.error) { 
       return callback(list.error); 
      } 
      callback(null, list.items); 
     }, 

     //------------------------------------------- 
     // Get the file information of the children. 
     // 
     // ref: https://developers.google.com/drive/v2/reference/files/get 
     //------------------------------------------- 
     function(children, callback) { 

      for(var i=0;i<children.length;i++) { 
       var file = fs.createWriteStream(children[i].title); 
       // Downnload and write file from google drive 
       (function(child) { 
        request.get(
         { url: child.downloadUrl 
         , encoding: null // Force Request to return the data as Buffer 
         , headers: 
         { Authorization: 'Bearer ' + _accessToken 
         } 
         } 
        , function done (err, res) { 
         res.pipe(file) 
         // If all is well, the file will be at res.body (buffer) 
         fs.writeFile('./' + child.title, res.body, function (err) { 
          if(!err) { 
           console.log('done') 
          } else { 
           console.log(err) 
          } 
          // Handle err somehow 
          // Do other work necessary to finish the request 
         }) 
         } 
        ) 

       })(children[i]) 
      } 
     } 
    ], 
    function(err, results) { 
     if (!err) { 
      console.log(results); 
     } 
    }); 
+0

Funziona come un fascino! Grazie! – MartinGian

Problemi correlati