如何使用AWS SDK(在Node.js中)中的putObject()将文件从HTTP响应体上载到S3?

如何使用AWS SDK(在Node.js中)中的putObject()将文件从HTTP响应体上载到S3?,node.js,amazon-web-services,amazon-s3,Node.js,Amazon Web Services,Amazon S3,我正在尝试使用AWS SDK将PDF文件保存到S3中。 我正在通过POST请求的正文(Application/PDF)获取PDF 使用fs.writeFile将文件保存到本地HD时,文件看起来正常。但是当上传到S3时,文件被破坏了(它只是一个文件) 第页(PDF) 任何帮助或暗示都将不胜感激 var data=body//POST请求中的body。 var fileName=“test.pdf”; writeFile(文件名,数据,{encoding:“binary”},函数(err,data)

我正在尝试使用AWS SDK将PDF文件保存到S3中。 我正在通过POST请求的正文(
Application/PDF
)获取PDF

使用
fs.writeFile
将文件保存到本地HD时,文件看起来正常。但是当上传到S3时,文件被破坏了(它只是一个文件) 第页(PDF)

任何帮助或暗示都将不胜感激

var data=body//POST请求中的body。
var fileName=“test.pdf”;
writeFile(文件名,数据,{encoding:“binary”},函数(err,data){
console.log('saved');//文件正常!
});
s3.putObject({Bucket:'bucketName',Key:fileName,Body:data},函数(err,data){
console.log('upload')//文件上载错误。
});
编辑:

如果我先写然后读文件,然后上传文件,它就会工作

fs.writeFile(文件名,数据,{encoding:“binary”},函数(err,data){
fs.readFile(文件名,函数(err,fileData){
s3.putObject({Bucket:“bucketName”,Key:fileName,Body:fileData},函数(err,data){
console.log('upload')//正确上载文件。
});
});
});

尝试将put上的contentType和/或ContentEncoding设置为S3

 ContentType: 'binary', ContentEncoding: 'utf8'

参见此处的代码示例了解工作示例

我认为这是因为数据被消耗(即流)

它将解释为什么在写入数据后,您不向S3发送任何内容,而再次读取数据后,您可以发送有效的PDF


尝试通过直接将数据发送到S3而不将其写入磁盘来查看它是否有效。

是的,您忘记了writeFile函数的回调,因此当您开始上传到Amazon S3时,您的文件没有完全保存。您不应该忘记node.js是异步的,当
fs.writeFile
完成工作时,应用程序不会等待,它只需同时运行
s3.putObject

/** *JS库:来自bluebirdjs的promisify.promisify **/

我的代码如下

global.Promise = require('bluebird');
const aws = require('aws-sdk');
const aswAccessKey = {
    accessKeyId: 'your-accesskey-id',
    secretAccessKey: 'your-secret-access-key'
};
const fs = require('fs');
const path = require('path');
const uuidV4 = require('uuid/v4');

// Create S3 service object
// available apiVersion: '2006-03-01', '2013-04-01',
const s3 = new aws.S3(Object.assign(aswAccessKey, {
    apiVersion: '2013-04-01'
}));

function putObject(bucketName, file) {
    console.log('putObject into ', bucketName);
    /**
     * If we don't use versioned bucket, we must not pass VersionId
     */
    const params = {
        Bucket: bucketName,
        Key: '',
        Body: 'Plain text',
        ACL: 'public-read',
        ContentType: 'binary',
        CacheControl: 'max-age=172800'
    };

    return Promise
        .promisify(fs.readFile, {
            context: fs
        })(file)
        .then((fileData) => {
            console.log(fileData);
            params.Body = fileData;
            params.Key = 'g01/' + uuidV4() + '-' + path.basename(file);
            return Promise
                .promisify(s3.putObject, {
                    context: s3
                })(params)
                .then((data) => {
                    console.log('successful');
                    console.log(data);
                })
                .catch((err) => {
                    console.log('Error', err);
                });
        })
        .catch(() => {
        });
}

是的,我知道这一点。我并行上传和保存只是为了证明数据没有损坏。顺便说一句,完整的数据可以在“var数据”中找到。然后,我认为,前面提到的编码(参数中的ContentEncoding和ContentType)有问题。我们不想看到代码,尝试给出相关解释,这将有助于理解它。