web-dev-qa-db-fra.com

Comment diffuser du contenu statique (images, polices, etc.) à l'aide d'un routeur en fer

Je viens de commencer à travailler avec un routeur en fer sur un météore. Je dois montrer une image sur la page d'accueil. J'ai pu configurer la route pour 'home' en utilisant le routage côté client. Pour les fichiers statiques, j'ai essayé de google et j'ai trouvé que l'ajout d'un itinéraire côté serveur pourrait aider. J'ai donc ajouté le code suivant sur router.js du serveur.

Router.map(function() {
    this.route('files', {
        path: '/files/:path(*)',
        action: function() {
            var path = this.params.path;

            console.log('will serve static content @ '+path);
            this.response.sendfile(path);
        }
    });
});

Lorsque j'essaie d'accéder à http://localhost:3000/files/someImage.png, il indique qu'aucun itinéraire n'est défini pour /files/someImage.png. Est-ce que je fais quelque chose de mal? Existe-t-il un autre moyen de servir des fichiers statiques en utilisant un routeur de fer?

29
Goje87

Au lieu de faire tout cela, vous pouvez simplement placer les fichiers dans votre répertoire public. Si vous ajoutez le fichier:

myApp/public/images/kitten.png

Vous pouvez y accéder à partir de vos modèles comme:

<img src="/images/kitten.png">

Aucun itinéraire n'est nécessaire pour que cela fonctionne.

Méfiez-vous de négliger la barre oblique de plomb.

<img src="images/kitten.png">

l'exemple ci-dessus fonctionnera à partir de vos itinéraires de niveau supérieur comme/books, ce qui le rend facile à manquer, mais échoue sur/books/pages.

61
David Weldon

Vous avez probablement juste besoin de vous assurer que la route se trouve dans une zone commune visible à la fois sur le client et le serveur (cette route s'exécute en fait sur le serveur) et spécifiez where: 'server'. De plus, nous devons charger le fichier réel hors du disque, ce qui signifie que nous avons besoin du chemin réel sur le serveur vers le fichier, et nous devons charger le "fs".

var fs = Npm.require('fs');

Router.map(function() {
  this.route('files', {
    path: '/files/:path(*)',
    where: 'server',
    action: function() {
        var path = this.params.path;
        var basedir = '~/app/';

        console.log('will serve static content @ '+ path);

        var file = fs.readFileSync(basedir + path);

      var headers = {
        'Content-type': 'image/png',
        'Content-Disposition': "attachment; filename=" + path
      };

      this.response.writeHead(200, headers);
      return this.response.end(file);
    }
  });
});

Quelques remarques: vous devriez probablement déplacer le code de téléchargement réel dans une fonction serveur uniquement et l'appeler à la place, en transmettant la réponse à la fonction.

Vous devez également valider le chemin afin de ne permettre à personne de télécharger arbitrairement des fichiers sur votre serveur.

De plus, cela définit explicitement le type de contenu, ce que vous voudrez probablement faire pour les images, mais peut-être pas pour les autres types de contenu. Pour un type générique, vous pouvez le définir sur application/octet-stream

Bien sûr, comme cela a été mentionné, si votre seul objectif est d'avoir du contenu statique disponible au moment du déploiement, vous devez simplement utiliser le /public répertoire.

5
MrMowgli

Il s'agit d'un bug dans iron-router , qui, selon eux, est corrigé, mais je rencontre toujours le problème et d'autres ont signalé sur ce problème github que c'était toujours un problème.

Edit: Il semble fonctionner pour les fichiers qui sont directement dans/public, mais pas pour les fichiers dans les dossiers dans/public.

4
foobarbecue