[英]Unable to download file from Google Drive using API - node.js
我正在嘗試使用node.js使用Google SDK API從Google驅動器下載文件。
但我無法在服務器端寫入/保存文件 - 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��∟I S�������W♥����Y
請幫助我知道我從Drive Api獲取的數據格式是什么,並以哪種格式編寫,以便我得到一個完整的.docx文件
編輯
如果它幫助我下載文件(.docx),我可以使用除xmlRequest之外的任何方法。
看來, node-XMLHttpRequest不支持二進制下載 - 請參閱此問題 。 您所看到的是文件的二進制內容轉換為String,在JavaScript中,它是二進制數據的不可逆和破壞性過程(這意味着您無法將字符串轉換回緩沖區並獲取與原始內容相同的數據)。
使用請求 ,您可以這樣下載二進制文件:
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
})
}
)
注意 :這會將整個文件緩沖到內存中,然后才能保存到磁盤。 對於小文件,這很好,但對於較大的文件,您可能希望將其實現為流式下載。 這個SO問題已經回答了,我建議你看看。
有關如何授權請求的詳細信息,請參閱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);
}
});
我剛剛遇到了這方面的問題,我已經提供了一個示例,說明了如何使用Google API Node.js庫實現這一點: https : //gist.github.com/davestevens/6f376f220cc31b4a25cd
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.