Google云端存储创建内容链接,行为不一致

时间:2016-11-18 16:04:12

标签: node.js google-cloud-storage

我正在开发一个使用Google云端存储的项目,允许用户使用Node.js将媒体文件上传到预定义的存储桶中。我一直在测试小.jpg个文件。我还使用gsutil将桶权限设置为public。

首先,所有文件都生成了下载文件的链接。在调查了文档之后,我了解到我可以使用Content-Type CLI在上传后显式设置每个文件的gsutil。当我使用此过程将文件类型设置为'image/jpeg'时,链接行为已更改为在浏览器中显示图像。但是,只有在使用gsutil更新元数据之前未先单击过该链接时,此方法才有效。我认为这可能是由于浏览器缓存造成的,但这种行为在隐身浏览器中是重复的。

使用gsutil设置mime类型无论如何都是不切实际的,所以我修改了节点服务器POST函数中的代码,使用npm在上传时设置元数据名为mime的模块。这是代码:

app.post('/api/assets', multer.single('qqfile'), function (req, res, next) {
    console.log(req.file);

    if (!req.file) {
        return ('400 - No file uploaded.');
    }

    // Create a new blob in the bucket and upload the file data.
    var blob = bucket.file(req.file.originalname);
    var blobStream = blob.createWriteStream();
    var metadata = {
        contentType: mime.lookup(req.file.originalname)
    };

    blobStream.on('error', function (err) {
        return next(err);
    });

    blobStream.on('finish', function () {

        blob.setMetadata(metadata, function(err, response){
            console.log(response);
             // The public URL can be used to directly access the file via HTTP.
        var publicUrl = format(
        'https://storage.googleapis.com/%s/%s',
        bucket.name, blob.name);
        res.status(200).send(
            {
                'success': true,
                'publicUrl': publicUrl,
                'mediaLink': response.mediaLink
            });
        });

    });

    blobStream.end(req.file.buffer);

});

这似乎有效,因为它确实在上传时设置了Content-Type,并且正确地反映在响应对象以及云存储控制台中。问题是返回的某些链接publicUrl会导致文件下载,而其他链接会导致浏览器加载图像。理想情况下,我希望有两个选项可用,但我无法看到存储文件或其元数据的任何差异。

我在这里缺少什么?

1 个答案:

答案 0 :(得分:0)

Google云端存储不会对上传对象的内容类型做出任何假设。如果您没有指定,GCS将只分配一种" application / octet-stream"。

然而,命令行工具gsutil更智能,并且会将正确的内容类型附加到大多数情况下上传的文件中,包括JPEG。

现在,您的浏览器可能会下载图片而不是显示图片有两个原因。首先,如果Content-Type设置为" application / octet-stream",大多数浏览器会将结果作为文件下载而不是显示它们。这可能发生在你的情况下。

第二个原因是服务器以“内容 - 处置:附件”作为回应。头。当您从主机" storage.googleapis.com"中获取GCS对象时,通常不会发生这种情况。正如您在上面所做的那样,但是如果您明确为您已上传的对象指定了contentDisposition,则可以这样做。

出于这个原因,我怀疑你的一些物品没有" image / jpeg"内容类型。您可以使用gsutil进行设置,如下所示:gsutil -m setmeta 'Content-Type:image/jpeg' gs://myBucketName/**