使用REST API从Amazon S3下载文件

Jay*_*ing 3 javascript rest amazon-s3 amazon-web-services hapijs

我有自己REST API的电话可以下载文件。(最后,文件可以存储在其他类型的服务器中……Amazon s3,本地等)

要从s3获取文件,我应该使用以下方法:

var url = s3.getSignedUrl('getObject', params);
Run Code Online (Sandbox Code Playgroud)

这会给我一个可下载的呼叫链接。

现在,我的问题是,当来自该链接的文件如何使用我自己的rest API来下载文件?有办法重定向呼叫吗?

我正在使用Hapi我的REST服务器。

{
    method: "GET", path: "/downloadFile",
    config: {auth: false},
    handler: function (request, reply) {
        // TODO
        reply({})
    }
},
Run Code Online (Sandbox Code Playgroud)

pet*_*teb 6

无需使用重定向下载所需文件,而只需从S3返回unbufferedStream即可。一个unbufferedStream可以从返回HttpResponseAWS-SDK。这意味着无需从S3下载文件,然后读入文件,然后让请求者下载文件。

仅供参考,我getObject()在Express中使用了这种方法,并且从未使用过Hapi,但是我认为我与路线定义非常接近,但希望它可以捕捉到我想要实现的实质。

Hapi.js路由

const getObject = require('./getObject');

{
    method: "GET", path: "/downloadFile",
    config: {auth: false},
    handler: function (request, reply) {
        let key = ''; // get key from request
        let bucket = ''; // get bucket from request

        return getObject(bucket, key)
          .then((response) => {
            reply.statusCode(response.statusCode);

            response.headers.forEach((header) => {
              reply.header(header, response.headers[header]);
            });

            return reply(response.readStream);
          })
          .catch((err) => {
            // handle err
            reply.statusCode(500);
            return reply('error');
          });
    }
},
Run Code Online (Sandbox Code Playgroud)

getObject.js

const AWS = require('aws-sdk');
const S3 = new AWS.S3(<your-S3-config>);

module.exports = function getObject(bucket, key) {
  return new Promise((resolve, reject) => {
    // Get the file from the bucket
    S3.getObject({
      Bucket: bucket,
      Key: key
    })
      .on('error', (err) => {            
        return reject(err);
      })
      .on('httpHeaders', (statusCode, headers, response) => {
        // If the Key was found inside Bucket, prepare a response object
        if (statusCode === 200) {
          let responseObject = {
            statusCode: statusCode,
            headers: {
              'Content-Disposition': 'attachment; filename=' + key
            }
          };

          if (headers['content-type'])
            responseObject.headers['Content-Type'] = headers['content-type'];
          if (headers['content-length'])
            responseObject.headers['Content-Length'] = headers['content-length'];

          responseObject.readStream = response.httpResponse.createUnbufferedStream();
          return resolve(responseObject);
        }
      })
      .send();
  });
}
Run Code Online (Sandbox Code Playgroud)