web-dev-qa-db-fra.com

Afficher le fichier PDF dans le navigateur à l'aide de js express

app.post('/asset', function(request, response){
  var tempFile="/home/applmgr/Desktop/123456.pdf";
  fs.readFile(tempFile, function (err,data){
     response.contentType("application/pdf");
     response.send(data);
  });
});

Je suis un nouveau bie à expressjs, je ne peux pas envoyer la réponse avec l'objet de données . Le contenu binaire est visible dans le navigateur .

26
Dexter

J'ai testé votre code et cela fonctionne pour moi en chrome avec une modification: Changez app.post en app.get

EDIT: puisque vous semblez penser qu’un serveur POST-only est une bonne idée, lisez ceci: http://net.tutsplus.com/tutorials/other/a-beginners-introduction-to-http-and-rest/ Faites défiler la liste jusqu'aux verbes HTTP et vérifiez la différence entre GET et POST. :)

Certaines recherches rapides suggèrent que d'autres navigateurs pourraient avoir d'autres problèmes, par exemple IE pourrait s'attendre à ce que l'URL se termine par .pdf. Depuis que je suis sur mon Mac, je ne peux pas tester ça pour toi;)

7
rdrey

Spécifier comment un téléchargement de fichier est géré revient à l'en-tête Content-disposition. Vous pouvez également spécifier le nom du fichier ici. Nous définissons également le Content-type pour nous assurer que le navigateur sait quoi faire avec le fichier qui lui est attribué.

Exemple Express.js:

app.post('/url/to/hit', function(req, res, next) {
  var stream = fs.readStream('/location/of/pdf');
  var filename = "WhateverFilenameYouWant.pdf"; 
  // Be careful of special characters

  filename = encodeURIComponent(filename);
  // Ideally this should strip them

  res.setHeader('Content-disposition', 'inline; filename="' + filename + '"');
  res.setHeader('Content-type', 'application/pdf');

  stream.pipe(res);
});

Maintenant, si vous regardez de plus près le Content-disposition, vous remarquerez que le champ inline; est ce qui définit la manière dont le navigateur réagit au fichier. Si vous souhaitez forcer les téléchargements, vous pouvez le faire en définissant inline; sur attachment;.

J'ai également découvert (en étant gravé plusieurs fois) que si vous définissez des caractères spéciaux dans votre nom de fichier, cela peut casser. Donc, je encodeURIComponent() le nom du fichier pour que cela ne se produise pas.

Espérons que cela aide les autres à essayer de comprendre la même chose!

Modifier

Entre le moment où je publiais ceci à l'origine et maintenant, j'ai découvert comment coder correctement le paramètre nom_fichier de content-disposition. Selon les spécifications, le nom du fichier doit être codé selon la norme RFC5987. J'ai fini par trouver un extrait de code exemple dans MDN qui gère correctement le codage ici (encodeURIComponent() n'est pas le format tout à fait correct pour ce champ).

MDN Snippet

var fileName = 'my file(2).txt';
var header = "Content-Disposition: attachment; filename*=UTF-8''" 
             + encodeRFC5987ValueChars(fileName);

console.log(header); 
// logs "Content-Disposition: attachment; filename*=UTF-8''my%20file%282%29.txt"

function encodeRFC5987ValueChars (str) {
    return encodeURIComponent(str).
        // Note that although RFC3986 reserves "!", RFC5987 does not,
        // so we do not need to escape it
        replace(/['()]/g, escape). // i.e., %27 %28 %29
        replace(/\*/g, '%2A').
            // The following are not required for percent-encoding per RFC5987, 
            // so we can allow for a little better readability over the wire: |`^
            replace(/%(?:7C|60|5E)/g, unescape);
}

Autre remarque, les navigateurs ne sont pas non plus conformes à la spécification. Certains caractères ne reviendront toujours pas correctement après un téléchargement (du moins lorsque je l'ai testé). 

Vous pouvez contourner le problème ce en mettant à jour le fonctionnement de vos téléchargements. Si votre URL de téléchargement se termine par le nom de fichier (et que vous ne fournissez pas d'attribut filename dans l'en-tête), il récupérera correctement le nom de fichier à partir de la valeur encodée de l'URL. IE 'http://subdomain.domain-url.com/some/path/to/downloads/' + encodeURIComponent("You're there, download this!.pdf")

Jeeze, et tout pour fournir un nom de fichier à vos téléchargements!

24
AlbertEngelB

Ma solution pour envoyer un PDF directement au navigateur:

app.get('/my/pdf', function (req, res) {
    var doc = new Pdf();
    doc.text("Hello World", 50, 50);

    doc.output( function(pdf) {
        res.type('application/pdf');
        res.end(pdf, 'binary');
    });
});

res.end () avec le second paramètre 'binary' a fait l'affaire dans mon cas. Autrement exprimer l'interpréter comme une chaîne

10
sja

C'est aussi simple que le code suivant:

var express = require('express'),
    fs = require('fs'),
    app = express();

app.get('/', function (req, res) {
    var filePath = "/files/my_pdf_file.pdf";

    fs.readFile(__dirname + filePath , function (err,data){
        res.contentType("application/pdf");
        res.send(data);
    });
});

app.listen(3000, function(){
    console.log('Listening on 3000');
});

Pour un rapport complet:

Clone node-cheat pdf_browser , lancez node app suivi de npm install express.

Heureux d'aider!

4

En fait, express a une fonction permettant d’envoyer un fichier à distance. Tout ce dont tu as besoin c'est :

app.get('/sendMePDF', function(req, res) {
  res.sendFile(__dirname + "/static/pdf/Rabbi.pdf");
})

Ici, le serveur enverra le fichier "Rabbi.pdf" et celui-ci s’ouvrira dans un navigateur comme vous ouvrez un fichier PDF dans un navigateur. J'ai placé le fichier dans le dossier "statique" mais vous pouvez le placer n'importe où, sachant que sendFile () prend en argument le chemin absolu (non relatif).

0
Peco