问题
I'm trying to get the zip file from a url for uploading it in the next step to Google drive. But my code doesn't work.
// The method to get the zip File from the url
function getFile(){
var file = request({
method : "GET",
url : "https://start.spring.io/starter.zip",
encoding: null // <- this one is important !
}, function (error, response, body) {
if(error || response.statusCode !== 200) {
// handle error
return;
}
JSZip.loadAsync(body).then(function (zip) {
return zip.file("content.txt").async("string");
}).then(function () {
console.log(text);
});
});
}
// method to upload zip to drive
function uploadFile(auth) {
const drive = google.drive({ version: 'v3', auth });
var fileMetadata = {
'name': 'demo.zip'
};
var media = {
mimeType: 'application/zip',
body: fs.createReadStream(getFile())
};
drive.files.create({
resource: fileMetadata,
media: media,
fields: 'id'
}, function (err, res) {
if (err) {
// Handle error
console.log(err);
} else {
console.log('File Id: ', res.data.id);
}
});
}
I want to get the zip file from the url above, but it throws an Exception:
new ERR_INVALID_ARG_TYPE(propName, ['string', 'Buffer', 'URL'], path);
When I change the body: fs.createReadStream(getFile())
to body: fs.createReadStream("https://start.spring.io/starter.zip")
the Exception is: no such file or directory, open 'https://start.spring.io/starter.zip
回答1:
- You want to download a zip file from URL and upload it to your Google Drive.
- You want to achieve this using googleapis with Node.js.
- You have already been able to get and put the file using Drive API.
If my understanding is correct, how about this modification?
Modification points:
- Value retrieved from the URL by
request
can be used for uploading. - The value retrieved from the URL is uploaded is buffer. So please convert it to the readstream type.
When above points are reflected to your script, it becomes as follows.
Modified script:
function getFile() {
return new Promise(function(resolve, reject) {
request(
{
method: "GET",
url: "https://start.spring.io/starter.zip",
encoding: null // <- this one is important !
},
function(error, response, body) {
if (error && response.statusCode != 200) {
reject(error);
return;
}
resolve(body);
}
);
});
}
function uploadFile(auth) {
const stream = require("stream"); // In this script, use this module.
getFile().then(body => {
const bs = new stream.PassThrough();
bs.end(body);
const drive = google.drive({ version: "v3", auth });
var fileMetadata = {
name: "demo.zip"
};
var media = {
mimeType: "application/zip",
body: bs // Modified
};
drive.files.create(
{
resource: fileMetadata,
media: media,
fields: "id"
},
function(err, res) {
if (err) {
// Handle error
console.log(err);
} else {
console.log("File Id: ", res.data.id);
}
}
);
});
}
Other pattern:
Of course, uploadFile()
can be also modified as follows.
async function uploadFile(auth) {
const stream = require("stream"); // In this script, use this module.
const buffer = await getFile();
const bs = new stream.PassThrough();
bs.end(buffer);
const drive = google.drive({ version: "v3", auth });
var fileMetadata = {
name: "demo.zip"
};
var media = {
mimeType: "application/zip",
body: bs // Modified
};
drive.files.create(
{
resource: fileMetadata,
media: media,
fields: "id"
},
function(err, res) {
if (err) {
// Handle error
console.log(err);
} else {
console.log("File Id: ", res.data.id);
}
}
);
}
References:
- Class: stream.PassThrough
- google-api-nodejs-client
- Files: create of Drive API v3
In my environment, I could confirm that this modified script worked. But if I misunderstood your question and this was not the result you want, I apologize.
来源:https://stackoverflow.com/questions/57365997/node-js-get-zip-from-a-url-and-upload-to-google-drive