无法使用API​​ – node.js从Google云端硬盘下载文件

我正尝试使用Node.js使用Google SDK API从谷歌驱动器下载文件。

但是我无法在服务器端写入/保存文件 – node.js

码:-

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

我在控制台中得到这个: – xhr.responseText的内容是这样的

   ▬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  ∟IS       W♥    Y 

请帮助我知道我从Drive Api获得的数据的格式是什么,并以哪种格式写入,以便获得完整的.docx文件

编辑

我可以使用任何方法,而不是xmlRequest,如果它可以帮助我下载文件(.docx)。

node-XMLHttpRequest似乎不支持二进制下载 – 请参阅此问题 。 你所看到的是将文件的二进制内容转换成string,在JavaScript中,这是对二进制数据(这意味着你不能将string转换回缓冲区并获得与原始内容相同的数据)的不可逆和破坏性的过程。

使用请求 ,你可以这样下载一个二进制文件:

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

注意 :这将把整个文件缓冲到内存中,然后才能保存到磁盘。 对于小文件,这没问题,但对于较大的文件,您可能需要考虑将其实施为stream式下载。 这个问题已经回答了,我build议你看看。

有关如何授权请求的更多信息,请参阅Google Developers文档 。

完整工作示例:从GoogleDrive – 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); } }); 

我只是有这个问题,我已经包括了一个例子,我如何设法使用谷歌API Node.js库工作: https : //gist.github.com/davestevens/6f376f220cc31b4a25cd