使用 Node.js 上传到谷歌云存储 [英] Uploading to google cloud storage with Node.js

查看:28
本文介绍了使用 Node.js 上传到谷歌云存储的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

Struggling with Node.js and Google cloud. I am trying to upload a file to a bucket in Google Cloud Storage. Basically I am using the code in this answer: https://stackoverflow.com/a/45253054/324691, but I can't get it to work. Here is my code:

const Storage = require('@google-cloud/storage');
const storage = new Storage();
var form = new formidable.IncomingForm();

// form.maxFieldsSize = 20 * 1024 * 1024; // default
form.maxFieldsSize = 20 * 1024;
// form.maxFileSize = 200 * 1024 * 1024;
// 4 MB / minute, 1 hour
form.maxFileSize = 4 * 60 * 1024 * 1024;
// Limit to 10 minutes during tests (4 MB/minute)
form.maxFileSize = 2 * 1024 * 1024;
form.maxFileSize = 4 * 10 * 1024 * 1024;

form.encoding = 'utf-8';
form.keepExtensions = true;
form.type = 'multipart';

return new Promise((resolve, reject) => {
    form.parse(req, (err, fields, files) => {
        console.warn("form.parse callback", err, fields, files);
        if (err) {
            reject(new Error(err));
            return;
        }
        var file = files.upload;
        if(!file){
            reject(new Error("no file to upload, please choose a file."));
            return;
        }
        console.info("about to upload file as a json: " + file.type);
        var filePath = file.path;
        console.log('File path: ' + filePath);
        console.log('File name: ' + file.name);

        var bucket = storage.bucket(bucketName)
        console.info("typeof bucket.upload", typeof bucket.upload);
        bucket.upload(filePath, {
            destination: file.name
        }).then(() => {
            resolve(true);  // Whole thing completed successfully.
            return true;
        }).catch((err) => {
            console.warn("catch bucket.upload, err", err);
            reject(new Error('Failed to upload: ' + JSON.stringify(err)));
        });
        console.warn("After bucket.upload");
    });
    console.warn("After form.parse");
}).then(() => {
    console.warn("form.parse then");
    res.status(200).send('Yay!');
    return true;
}).catch(err => {
    console.warn("form.parse catch");
    console.error('Error while parsing form: ' + err);
    res.status(500).send('Error while parsing form: ' + err);
});

The output in the console log looks ok (including file.path and file.name), but when it gets to bucket.upload (which is of type function) then it crashes with the error Error while parsing form: Error: Failed to upload: {"message":"Error during request."}. And then it says Execution took 1910 ms, user function completed successfully. And after that finally Function worker killed by signal: SIGTERM.

I have been testing using bucketName with and without "gs://".

And I have been testing different ways for authorization:

const storage = new Storage({ projectId: projectId });
const storage = new Storage({ keyFileName: 'path-to-keyfile.json'});
const storage = new Storage();

The key file is a key file for the service account (see https://cloud.google.com/docs/authentication/getting-started).

This is a Firebase project and I am testing on the local Firebase server (firebase serve --only functions,hosting).

What could be wrong here?

解决方案

The authentication of the storage should look like this:

const storage = new Storage({
    apiKey: "YOUR_API_KEY",
    authDomain: "YOUR_AUTH_DOMAIN",
    databaseURL: "YOUR_DATABASE_URL",
    projectId: "YOUR_PROJECT_ID",
    storageBucket: "YOUR_STORAGE_BUCKET",
    messagingSenderId: "YOUR_MESSAGE_SENDER_ID"
});

Also working with multipart looks different than with local files. So the code for uploading would be:

            const fileName = 'file_name.extension";

            const fileUpload = bucket.file(fileName);

            const uploadStream = fileUpload.createWriteStream({
                metadata: {
                    contentType: file.mimetype
                }
            });


            uploadStream.on('error', (err) => {
                console.log(err);
                return;
            });

            uploadStream.on('finish', () => {
                console.log('Upload success');
            });

            uploadStream.end(file.buffer);

Lastly, bucketName shouldn't contain gs:// - it should look like this: project_id.appspot.com.

Ps. Uploading mimetype was handled with busboy in the code above.

这篇关于使用 Node.js 上传到谷歌云存储的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆