当前位置 : 主页 > 网页制作 > Nodejs >

Node.js流直接上传到Google云端存储

来源:互联网 收集:自由互联 发布时间:2021-06-16
我在Google Compute VM实例上运行了一个Node.js应用程序,它直接从POST请求(而不是通过浏览器)接收文件上传,并将传入的数据流式传输到Google云端存储(GCS). 我正在使用Restify b / c我不需要Expre
我在Google Compute VM实例上运行了一个Node.js应用程序,它直接从POST请求(而不是通过浏览器)接收文件上传,并将传入的数据流式传输到Google云端存储(GCS).

我正在使用Restify b / c我不需要Express的额外功能,因为它可以轻松传输传入的数据.

我为该文件创建一个随机文件名,获取传入的req并将其丢给一个整齐的GCS小节点包装器(在这里找到:https://github.com/bsphere/node-gcs),它向GCS发出PUT请求.使用PUT的GCS文档可以在这里找到:https://developers.google.com/storage/docs/reference-methods#putobject …如果使用分块传输编码,则表示不需要Content-Length.

好消息:文件正在相应的GCS存储“桶”中创建!

坏消息:

>我还没弄明白如何从Restify获取传入文件的扩展名(注意我手动设置’.jpg’和手动内容类型).
>该文件正在经历轻微的损坏(几乎可以肯定的是我对PUT请求做错了).如果我从谷歌下载POSTed文件,OSX告诉我它已损坏……但是,如果我使用PhotoShop,它会打开并且看起来很好.

更新/解决方案

正如vkurchatkin所指出的,我需要解析请求对象,而不是仅将整个事物传递给GCS.在尝试了较轻的busboy模块之后,我认为使用multiparty要容易得多.为了动态设置Content-Type,我只使用了Mimer(https://github.com/heldr/mimer),引用了传入文件的文件扩展名.重要的是要注意,因为我们正在管道部件对象,所以必须清除part.headers.否则,非预期信息(特别是内容类型)将被传递,并且可能/将与我们尝试明确设置的内容类型冲突.

以下是适用的修改后的代码:

var restify = require('restify'),
    server = restify.createServer(),
    GAPI = require('node-gcs').gapitoken,
    GCS = require('node-gcs'),
    multiparty = require('multiparty'),
    Mimer = require('mimer');

server.post('/upload', function(req, res) {

    var form = new multiparty.Form();

    form.on('part', function(part){
        var fileType = '.' + part.filename.split('.').pop().toLowerCase();
        var fileName = Math.random().toString(36).slice(2) + fileType;

        // clear out the part's headers to prevent conflicting data being passed to GCS
        part.headers = null;

        var gapi = new GAPI({
            iss: '-- your -- @developer.gserviceaccount.com',
            scope: 'https://www.googleapis.com/auth/devstorage.full_control',
            keyFile: './key.pem'
        }, 
        function(err) {
            if (err) { console.log('google cloud authorization error: ' + err); }

            var headers = {
                'Content-Type': Mimer(fileType),
                'Transfer-Encoding': 'Chunked',
                'x-goog-acl': 'public-read'
            };

            var gcs = new GCS(gapi);

            gcs.putStream(part, myBucket, '/' + fileName, headers, function(gerr, gres){
                console.log('file should be there!');
            });
        });
    });
};
您不能使用原始req流,因为它会生成整个请求主体,这是多部分.您需要使用诸如 multiparty之类的内容来解析请求,为您提供所需的所有元数据.
网友评论