【问题标题】:AWS uploading a photo to s3 bucket using Node.jsAWS 使用 Node.js 将照片上传到 s3 存储桶
【发布时间】:2018-08-29 23:31:17
【问题描述】:

我无法将照片上传到我的 s3 存储桶。我认为这是一个凭据错误。我可以使用 aws cli 上传照片,但无法使用此 node.js 代码上传(我得到了超时):

var config = require('./config.json');
var AWS = require('aws-sdk');
AWS.config.update({region:config.awsRegion});
var s3 = new AWS.S3();
var fs = require('fs');



 module.exports.upload = function(fileName, cb){
   var bitmap = fs.readFileSync('./photos/'+fileName);

   var params = {
     Body: bitmap,
     Bucket: config.s3Bucket,
     Key: fileName
    };
    s3.putObject(params, function(err, data) {
      fs.exists('./photos/'+fileName, function(exists) {
        if(exists) {

          fs.unlink('./photos/'+fileName);
        }
        });

      if (err) {
        console.log(err, err.stack);
        cb(err);
      }else{
        //console.log(data);
        cb(null,data);           // successful response
      }

    });
}

有人知道吗?

这里是主服务器代码:

const express    = require('express');        // call express
const app        = express();                 // define our app using express
const bodyParser = require('body-parser');
const basicAuth = require('express-basic-auth');
const Raspistill = require('node-raspistill').Raspistill;
const camera = new Raspistill({
    width: 600,
    height: 600,
    time:1
});


const s3upload = require('./upload-s3');
const speaker = require('./speaker');
const faceSearch = require('./search-faces');


app.use(basicAuth({
    users: { 'raspi': 'secret' }
}))

// configure app to use bodyParser()
// this will let us get the data from a POST
app.use(bodyParser.urlencoded({ extended: true }));
app.use(bodyParser.json());

var port = process.env.PORT || 80;        // set our port

// ROUTES FOR OUR API
// =============================================================================
var router = express.Router();              // get an instance of the express Router

// test route to make sure everything is working (accessed at GET http://localhost:8080/api)
router.get('/', function(req, res) {
    res.json({ message: 'hooray! welcome to our api!' });
});
router.post('/capture', function(req, res) {
  var fileName = new Date().getTime()+".jpg";
  console.log('filename', fileName);
  camera.takePhoto(fileName).then((photo) => {
    console.log('photo captured');
    //speaker.speak('Image has been captured... ');
    s3upload.upload(fileName, function(err,data){
        if(err){
          res.json({ status: 'fail' });
        }else{
          console.log('uploaded image to s3 bucket: '+fileName);
          //speaker.speak('Image has been uploaded to S3 bucket raspi118528');
          faceSearch.search(fileName, function(err, data){


            if(!err){

              if(data.FaceMatches && data.FaceMatches.length>0){

                  //var text = 'Hello '+data.FaceMatches[0].Face.ExternalImageId + '. How are you?';
                  var text = data.FaceMatches[0].Face.ExternalImageId ;
                  // text += Number.parseFloat(data.FaceMatches[0].Similarity).toFixed(2)+' % confident that you are '+
                  // data.FaceMatches[0].Face.ExternalImageId;
                  //speaker.speak(text);
                  res.json({ status: 'matched', key: fileName ,message: text});

              }else{
                  res.json({ status: 'unmatched', key: fileName ,message: "Hello! We never met before. What's your name?"});
                  //speaker.speak("Hello! We never met before. What's your name?");
              }
            }else{

              //speaker.speak("I can's see any faces. Are you human?");
                res.json({ status: 'error', key: fileName ,message: "I can's see any face. Please come in front of camera?"});
            }
          })

        }
    })
  });

});
// more routes for our API will happen here

// REGISTER OUR ROUTES -------------------------------
// all of our routes will be prefixed with /api
app.use('/api', router);

// START THE SERVER
// =============================================================================
app.listen(port);
console.log('Magic happens on port ' + port);

再次,我可以使用 aws s3 cp cat.jpg s3://raspberrypijohnypie/ --region us-east-1 上传照片

但是,我的凭据一定有问题。这是因为我的服务器抓拍图片并存入photos文件夹后,无法上传。

【问题讨论】:

  • 您的标签表示 aws-lambda,但我没有看到任何 Lambda 代码。这是拉姆达吗?凭证问题通常不会产生超时。您是否在 VPC 中的 Lambda 中运行此程序(没有到 Internet 的路由)?
  • 对不起,我只是想我需要更多的标签。这是我的 lambda 调用的服务器的一部分。运行 lambda 没有问题。我会在我的 OP 中添加更多信息
  • 我只需要以 sudo 用户身份更新我的 aws 凭据

标签: amazon-web-services amazon-s3 aws-sdk aws-cli


【解决方案1】:

您的代码似乎没问题,但您没有明确传递任何凭据。如果您在 EC2 实例或附加角色的 Lambda 函数中运行它,或者如果您在本地运行代码但具有包含您的凭证集的环境变量,则可以。没有它们不会导致超时,而是 putObject 函数会返回 403 错误。

我建议您注释掉您检查和删除文件的部分,并查看执行是否至少达到了该点,如果是,它会抛出什么错误(一旦文件没有在您的存储桶中结束,我假设发生了错误)。

如果您想尝试通过显式传递您的凭据进行测试,那么您应该像这样实例化您的 S3 客户端

var s3 = new AWS.S3({
    apiVersion: '2006-03-01',
    accessKeyId: '',
    secretAccessKey: ''
});

另一个(不相关的)要点是,在检查错误之前删除您的照片是危险的。如果发生任何错误,您将永远失去它。您应该在错误检查后移动删除逻辑。

【讨论】:

  • 嗯...现在我的“你好”意图不起作用。感谢您的彻底回复!我应该提到这不是我的代码。我正在学习一个非常乐于助人的人 Mithun 的教程:github.com/just4give/raspi-dexter-lambda
  • 我认为您还需要在某些时候指定区域才能使 s3 / aws sdk ...
【解决方案2】:

似乎您需要传递凭据。最好允许代码从 aws 凭证文件中读取凭证。所以步骤是:
1. 在您的主目录中创建 .aws 文件夹。
2. 在里面导航并创建一个名为“凭据”的文件
3. 在顶部添加一个“[默认]”,然后将您的区域和两个访问密钥添加到另一行下方。
4. 在你的代码中,这样读:

const credentials = new AWS.SharedIniFileCredentials({profile: 'default'});  
AWS.config.credentials = credentials;  

在上述行之后,您可以初始化您的 S3 对象并尝试执行 CRUD 操作。

P.S.:既然你可以使用 aws-cli,你应该已经有 .aws 文件夹设置了!

【讨论】:

    猜你喜欢
    • 2019-03-18
    • 2017-12-23
    • 1970-01-01
    • 1970-01-01
    • 2018-04-25
    • 2018-07-03
    • 1970-01-01
    • 2019-04-28
    • 2020-12-30
    相关资源
    最近更新 更多