Failed to load file from Google Drive using API - node.js

I am trying to download a file from Google Drive using the Google SDK API using node.js.

But I can not write / save the file on the server side - node.js

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

I get this in the console : - The content of xhr.responseText is something like this

   ▬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 

Please help me find out what format of data I get from Api Disk and write it in which format to get the full .docx file

Edit

I am open to using any method other than xmlRequest if it helps me upload a file (.docx).

+5
source share
3 answers

node-XMLHttpRequest doesn't seem to support binary downloads - see this question . What you see is the binary content of the file converted to String, which in JavaScript is an irreversible and destructive process for binary data (this means that you cannot convert the string back to the buffer and get the same data as the original content )

Using request , you can download the binary as follows:

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

Note This will cause the entire file to be saved in memory until it is saved to disk. For small files, this is good, but for large files, you might want to study this as a streaming download. This SO question already answers this, I recommend you take a look.

More information on how to resolve your requests can be found on the Google Developers docs .

+10
source

Full working example: downloading a file from 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); } }); 
+2
source

I had problems with this, I included an example of how I was able to do this using the Google API library Node.js: https://gist.github.com/davestevens/6f376f220cc31b4a25cd

+2
source

Source: https://habr.com/ru/post/1216176/


All Articles