1

Dans mon application serverless, je veux créer un pdf qui est généré dynamiquement, puis télécharger ce fichier pdf créé en aws s3. Mon problème est, quand une URL est retournée au code côté client du serveur, l'URL téléchargée ne fonctionne pas. Mon code est donné ci-dessous:télécharger le pdf généré dynamiquement à partir aws-lambda dans aws-s3

code javascript côté client (de angularjs)

$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); 
     }); 
    }; 

Serverless code

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 
        }); 
       } 

      }); 

     } 
    } 
}; 
+1

Quel est votre problème? Qu'est-ce qui ne fonctionne pas? Quelle erreur voyez-vous? – garnaat

Répondre

3

J'ai résolu mon problème. J'essayais de télécharger le pdf avant de générer le pdf. Je résoudre ce problème en utilisant le code suivant:

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 
        }); 

        } 

       }); 

      }); 
     } 
    }); 
+1

Ce code suppose que votre fichier sera toujours complètement écrit en moins de 250 millisecondes. Il serait plus sûr d'écouter l'événement stream 'finished': http://stackoverflow.com/questions/11447872/callback-to-handle-completion-of-pipe –

+0

merci, j'ai changé comme tu l'as dit et ça marche très bien – sabbir

0

Je l'ai fait genre de chose semblable auparavant.
Je veux quelques clarifications de votre part et ensuite je serai en mesure de vous aider à mieux.
1) Dans votre code (côté serveur), vous avez mentionné dans la fonction de rappel que le lien aws réel est retourné. Etes-vous sûr que votre fichier est téléchargé sur Amazon s3? Je veux dire, avez-vous vérifié votre seau pour le fichier ou non?
2) Avez-vous défini une stratégie de compartiment personnalisé sur Amazon s3? La stratégie de compartiment joue un rôle important dans ce qui peut être téléchargé à partir de S3.
3) Avez-vous vérifié les journaux pour voir exactement quelle partie du code causait l'erreur? S'il vous plaît me fournir cette information et je pense que je devrais être en mesure de vous aider.

0

si nous ne voulons pas télécharger à s3 juste retour fichier généré à partir aws-lambda.