【问题标题】:upload dynamically generated pdf from aws-lambda into aws-s3从 aws-lambda 将动态生成的 pdf 上传到 aws-s3
【发布时间】:2016-06-03 11:01:58
【问题描述】:

在我的serverless 应用程序中,我想创建动态生成的pdf,然后将创建的pdf 上传到aws s3。我的问题是,当一个 url 从服务器返回到客户端代码时,上传的 url 不起作用。我的代码如下:

客户端 javascript 代码 (angular.js)

 $scope.downloadAsPDF = function() {

    // first I have to sent all html data into server
    var html = angular.element('html').html(); // get all page data

    var service = API.getService();
    service.downloadPdf({}, { html : html },   // api call with html data
      function(res) {
        console.log("res : ", res);
        window.open(res.url);   // open uploaded pdf file
                               // err: The server replies that you don't have permissions to download this file
                               // HTTP/1.1 403 Forbidden
      }, function(err) {
        console.log("err : ", err);
      });
  };

无服务器代码

var fs = require('fs');
var pdf = require('html-pdf');

var AWS = require("aws-sdk");
var s3 = new AWS.S3();

module.exports.handler = function(event, context) {

    if (event.html) {   // client html data

    AWS.config.update({
        accessKeyId:  'xxxxxxxxxxxxxxxxx',
        secretAccessKey:  'xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx',
        region: 'xxxxxxxxxxxxxxxxxxxx'
    });

    var awsInfo = {
        bucket: 'xxxxx-xxxxxx'
    };

    var baseUrl = 'https://s3-my-region.amazonaws.com/s3-upload-directory';
    var folderRoot = 'development/pdf';

    // unique file name
    var output_filename = Math.random().toString(36).slice(2) + '.pdf';

    // file created directory
    var output = '/tmp/' + output_filename; 

    pdf.create(event.html, options).toStream(function(err, stream) {

       if( err ) {
           console.log('pdf err : ', err);
       } else {

            writeStream =fs.createWriteStream(output);

             s3.putObject({
                Bucket : awsInfo.bucket,
                Key : folderRoot + '/' + output_filename,
                Body :  fs.createReadStream(output),
                ContentType : "application/pdf"
             },
             function(error, data) {

                if (error != null) {
                   console.log("error: " + error);
                } else {
                    // upload data:  { ETag: '"d41d8cd98f00b204e9800998ecf8427e"' }
                    console.log('upload data : ', data);

                   return cb(null, {
                       // return actual aws link, but no file
                       // ex: 'https://s3-my-region.amazonaws.com/s3-upload-directory/output_filename.pdf
                       url:  baseUrl +  '/' + output_filename
                   });
                }

             });

         }
    }
};

【问题讨论】:

  • 你的问题是什么?什么不工作?你看到了什么错误?

标签: angularjs node.js amazon-s3 aws-lambda serverless-framework


【解决方案1】:

我已经解决了我的问题。在生成pdf之前,我试图上传pdf。我已经使用以下代码解决了这个问题:

  pdf.create(event.html, options).toStream(function(err, stream) {
      if (err) {
          console.log('pdf err : ', err);
      } else {
           var stream = stream.pipe(fs.createWriteStream(output));

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

            s3.putObject({
                  Bucket : awsInfo.bucket,
                  Key : folderRoot + '/' + output_filename,
                  Body :  fs.createReadStream(output),
                  ContentType : "application/pdf"
                },
                function(error, data) {

                  if (error != null) {
                    console.log("error: " + error);
                    return cb(null, {
                      err:  error
                    });
                  } else {

                    var url =  baseUrl +  '/' + output_filename

                    return cb(null, {
                      url: url
                    });

                  }

                });

          });
      }
  });

【讨论】:

  • 该代码假定您的文件将始终在 250 毫秒内完全写入。监听流finished事件会更安全:stackoverflow.com/questions/11447872/…
  • 谢谢你,我已经按照你说的做了修改,效果很好
【解决方案2】:

我以前做过类似的事情。
我想从你那里得到一些澄清,然后我就能更好地帮助你。
1)在您的代码(服务器端)中,您在回调函数中提到实际的 aws 链接正在返回。 您确定您的文件正在上传到 Amazon s3。我的意思是您是否检查了您的存储桶中的文件?
2)您是否在 Amazon s3 上设置了任何自定义存储桶策略。存储桶策略在可以从 S3 下载的内容中发挥重要作用。
3)您是否检查了日志以确切了解导致错误的代码部分? 请向我提供此信息,我认为我应该能够帮助您。

【讨论】:

    【解决方案3】:

    如果我们不想在 s3 上传,只需从 aws-lambda 返回生成的文件。

    【讨论】:

      猜你喜欢
      • 2016-03-19
      • 2018-07-12
      • 1970-01-01
      • 2022-07-29
      • 2020-02-09
      • 2021-02-07
      • 2017-09-04
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多