【问题标题】:How to upload a file from the browser to Amazon S3 with node.js, Express, and knox? [closed]如何使用 node.js、Express 和 knox 将文件从浏览器上传到 Amazon S3? [关闭]
【发布时间】:2011-10-10 02:13:53
【问题描述】:

我正在尝试查找一些使用 node.js、Express 和 knox 的示例代码。

Knox 的文档仅给出了如何上传已存储在文件系统中的文件的清晰示例。 https://github.com/learnboost/knox#readme

此外,还有一些简单的教程(甚至在 Express 本身中)关于如何直接上传文件以表达并保存到文件系统。

我很难找到一个示例,它允许您将客户端上传上传到节点服务器并将数据直接流式传输到 S3,而不是先存储在本地文件系统中。

谁能指出包含此类信息的要点或其他示例?

【问题讨论】:

  • Andrew Barber,怎么不清楚他们在问什么?大多数回答这个问题的人似乎都没有问题理解它。
  • 同意。重量级为什么要关闭一个已有 2 年历史且已更新有价值信息的问题?此外,关闭它会破坏它所获得的 seo 价值。
  • 对我来说这个问题很清楚,如果你不明白这个话题的重点,那可能只是意味着你不应该给出答案,因为你对那个话题不够深入.

标签: node.js upload amazon-s3 express


【解决方案1】:

之前的所有答案都涉及让上传通过您的 node.js 服务器,这是低效且不必要的。您的节点服务器无需处理上传文件的带宽或处理,因为 Amazon S3 允许直接从浏览器上传

看看这篇博文:http://blog.tcs.de/post-file-to-s3-using-node/

我还没有尝试过那里列出的代码,但是在查看了它之后,它看起来很可靠,我很快就会尝试实现它,广告会用我的发现更新这个答案。

【讨论】:

  • “之前的所有答案都涉及让上传通过你的 node.js 服务器,这是低效且不必要的。”但在我回答时(2011 年),您的解决方案不可用。但我同意:现在,这是最好的方法。
  • 我正在使用一个 s3“兼容”服务(来自 cloudfoundry 的 vBlob),它不接受 method="post",而只接受 method="put"。有什么想法吗?
  • 在客户端使用亚马逊代码不是不安全吗?
  • 您的 amazon/s3 代码不在客户端,它们保存在服务器端(节点端点进入的地方),并在向 s3 的上传请求发送之前被编码并提供给客户端制作
  • 如果攻击者在客户端代码中使用 amazon id 并耗尽您的存储空间怎么办?
【解决方案2】:

以下是使用multipartyknox 直接流式传输到s3 而不接触硬盘的示例:

var http = require('http')
  , util = require('util')
  , multiparty = require('multiparty')
  , knox = require('knox')
  , Batch = require('batch')
  , PORT = process.env.PORT || 27372

var s3Client = knox.createClient({
  secure: false,
  key: process.env.S3_KEY,
  secret: process.env.S3_SECRET,
  bucket: process.env.S3_BUCKET,
});

var Writable = require('readable-stream').Writable;
util.inherits(ByteCounter, Writable);
function ByteCounter(options) {
  Writable.call(this, options);
  this.bytes = 0;
}

ByteCounter.prototype._write = function(chunk, encoding, cb) {
  this.bytes += chunk.length;
  cb();
};

var server = http.createServer(function(req, res) {
  if (req.url === '/') {
    res.writeHead(200, {'content-type': 'text/html'});
    res.end(
      '<form action="/upload" enctype="multipart/form-data" method="post">'+
      '<input type="text" name="path"><br>'+
      '<input type="file" name="upload"><br>'+
      '<input type="submit" value="Upload">'+
      '</form>'
    );
  } else if (req.url === '/upload') {
    var headers = {
      'x-amz-acl': 'public-read',
    };
    var form = new multiparty.Form();
    var batch = new Batch();
    batch.push(function(cb) {
      form.on('field', function(name, value) {
        if (name === 'path') {
          var destPath = value;
          if (destPath[0] !== '/') destPath = '/' + destPath;
          cb(null, destPath);
        }
      });
    });
    batch.push(function(cb) {
      form.on('part', function(part) {
        if (! part.filename) return;
        cb(null, part);
      });
    });
    batch.end(function(err, results) {
      if (err) throw err;
      form.removeListener('close', onEnd);
      var destPath = results[0]
        , part = results[1];

      var counter = new ByteCounter();
      part.pipe(counter); // need this until knox upgrades to streams2
      headers['Content-Length'] = part.byteCount;
      s3Client.putStream(part, destPath, headers, function(err, s3Response) {
        if (err) throw err;
        res.statusCode = s3Response.statusCode;
        s3Response.pipe(res);
        console.log("https://s3.amazonaws.com/" + process.env.S3_BUCKET + destPath);
      });
      part.on('end', function() {
        console.log("part end");
        console.log("size", counter.bytes);
      });
    });
    form.on('close', onEnd);
    form.parse(req);

  } else {
    res.writeHead(404, {'content-type': 'text/plain'});
    res.end('404');
  }

  function onEnd() {
    throw new Error("no uploaded file");
  }
});
server.listen(PORT, function() {
  console.info('listening on http://0.0.0.0:'+PORT+'/');
});

示例取自https://github.com/superjoe30/node-multiparty/blob/master/examples/s3.js

【讨论】:

  • 感谢您,希望您能在此处为我的问题提供帮助:stackoverflow.com/q/21873561/971592
  • @andrewrk 在上面提到的答案中,我应该如何在文件上传完成之前停止它。示例:文件当前正在上传,我意识到文件太大,所以我想通过发送适当的消息来停止上传。我的节点服务器挂起,因为当我希望停止上传时没有发回正确的响应。 stackoverflow.com/questions/33452952/…
【解决方案3】:

node/express 代码不适用于 nodejs v0.4.7

这里是 nodejs v0.4.7 的更新代码

app.post('/upload', function (req, res) {
  // connect-form additions
  req.form.complete(function (err, fields, files) {
    // here lies your uploaded file:
    var path = files['upload-file']['path'];
    // do knox stuff here
  });
});

【讨论】:

    【解决方案4】:

    * 更新 *

    截至 2009 年年中,亚马逊支持 CORS,并且不再需要通过您的 node.js 服务器上传。您可以直接将文件上传到 S3。


    在“connect-form”模块的帮助下,您可以将文件上传到您的服务器(通过普通的多部分 FORM),然后处理 S3 的东西......

    <form action="/upload" method="POST" id="addContentForm" enctype="multipart/form-data">
      <p><label for="media">File<br/><input type="file" name="media" /></label></p>
      <p><button type="submit">upload</button></p>
    </form>
    

    节点/快递代码:

    app.post('/upload', function (req, res) {
      // connect-form additions
      req.form.complete(function (err, fields, files) {
        // here lies your uploaded file:
        var path = files['media']['path'];
        // do knox stuff here
      });
    });
    

    您必须将以下行添加到应用配置中:

    app.configure(function(){
      // rest of the config stuff ...
      app.use(form({ keepExtensions: true }));
      // ...
    });
    

    【讨论】:

    • 有趣!在考虑客户端直接上传到 S3 时,我们必须采取哪些安全预防措施?我想我们不想给任何人和每个人这种能力。谢谢:)
    • talentedmrjones 提供了一个容易受到中间人攻击的解决方案。这里给出了另一种解决方案terlici.com/2015/05/23/uploading-files-s3.html,这是正确的。但它有一些限制,比如你不能提及文件大小等。
    【解决方案5】:

    connect-stream-s3 库可以将您的所有表单文件作为中间件的一部分上传到 S3,因此您不必自己执行任何逻辑。它目前需要 express.bodyParser() 才能工作,但我正在开发一个版本,该版本将在写入磁盘之前将文件直接流式传输到 Amazon S3:

    请告诉我你的进展如何。希望一旦你在你的页面处理程序中,它比你自己做的麻烦少得多。 :)

    【讨论】:

      【解决方案6】:

      我这样做是为了直接从 Jquery File Upload 插件上传到 S3,文件是公开的 - 它应该为您指明正确的方向。

      https://gist.github.com/3995819

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2023-03-23
        • 1970-01-01
        • 1970-01-01
        • 2013-09-06
        • 1970-01-01
        • 2011-11-22
        • 2021-06-10
        • 1970-01-01
        相关资源
        最近更新 更多