2015-03-26 13 views
5

Próbuję pobrać plik z dysku Google za pomocą interfejsu API Google SDK API przy użyciu pliku node.js.Nie można pobrać pliku z Dysku Google przy użyciu interfejsu API - node.js

Ale nie jestem w stanie napisać/zapisz plik na stronie serwera - node.js

Code: -

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

jestem coraz to w konsoli: - Treść XHR .responseText to coś takiego:

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

Proszę mi pomóc znać co to jest format danych Dostaję z dysku Api i zapisać go w formacie, który tak, że mam pełną .docx plik

Edit

Jestem otwarty na wszelkie metody użyć innego niż xmlRequest jeśli pomaga mi pobrać plik (.docx). Wydaje się, że

+1

Twoim głównym priorytetem powinno być ustalenie, jak odzyskać dane w postaci bufora - gdy tylko dane binarne zostaną przekształcone w ciąg, dane zostaną uszkodzone. Korzystając z modułu Request.js, musisz ustawić kodowanie: null w opcjach żądania. Ale z Xhr, nie jestem pewien. –

+0

Czego się spodziewałeś? Funkcja downloadUrl jest używana tylko w przypadku plików innych niż Google. Jeśli jest to dokument Google, użyjesz jednego z linków do eksportu. – pinoyyid

+1

@pinoyyid, cokolwiek może być wyjściem, chcę tylko zapisać/zapisać/pobrać dane w poprawnym formacie, w moim przypadku jest to plik .docx i po pobraniu go na serwer, muszę edytować ten plik .docx –

Odpowiedz

10

node-XMLHttpRequest nie obsługuje plików binarnych - patrz this issue. To, co widzisz, to zawartość binarna pliku przekonwertowana na String, która w języku JavaScript jest nieodwracalnym i destrukcyjnym procesem dla danych binarnych (co oznacza, że ​​nie możesz przekonwertować ciągu z powrotem na bufor i uzyskać te same dane, co oryginalna zawartość).

Korzystanie request, można pobrać plik binarny w ten sposób:

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

Uwaga: To bufor cały plik do pamięci, zanim będzie mogła być zapisana na dysku. W przypadku małych plików jest to w porządku, ale w przypadku większych plików możesz zajrzeć do implementacji jako pobierania strumieniowego. This SO question już odpowiedzi, polecam spojrzeć.

Więcej informacji na temat autoryzacji wniosków można znaleźć na stronie Google Developers docs.

+0

Próbowałem z Request, a następnie otrzymuję pusty bufor. –

+0

Co jest w 'err'? Sprawdź również "res.statusCode", nie powinien być w zakresie 4xx lub 5xx. Najlepiej zrzuć oba obiekty do konsoli i dokładnie sprawdź odpowiedź. –

+0

uzyskiwanie 401 i musi być, ponieważ nie przekazałem AccessToken. Na życzenie gdzie mogę dodać accessTOken? –

2

Kompletny przykład roboczy: Pobieranie plików z Dysk Google - node.js API

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

Działa jak urok! Dzięki! – MartinGian

Powiązane problemy