Как обслуживать статический контент (изображения, шрифты и т. д.) с помощью железного маршрутизатора

Я только начал работать с железным роутером на метеоре. Мне нужно показать изображение на главной странице. Мне удалось настроить маршрут для «дома», используя маршрутизацию на стороне клиента. Для статических файлов я попытался найти Google и обнаружил, что может помочь добавление маршрута на стороне сервера. Итак, я добавил следующий код на сервер router.js.

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

Когда я пытаюсь получить доступ к http://localhost:3000/files/someImage.png, он говорит, что для /files/someImage.png не определен маршрут. Я делаю что-то неправильно? Есть ли другой способ обслуживать статические файлы с помощью железного маршрутизатора?


person Goje87    schedule 24.01.2014    source источник
comment
Обратите внимание, чтобы не обслуживать большие файлы, используя это, это плохо работает с большими файлами.   -  person ApriOri    schedule 14.09.2018


Ответы (3)


Вместо того, чтобы делать все это, вы можете просто поместить файлы в свой каталог public. Если вы добавите файл:

myApp/public/images/kitten.png

Вы можете получить к нему доступ из своих шаблонов, таких как:

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

Для этого не нужны никакие маршруты.

Остерегайтесь упускать из виду косую черту.

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

приведенный выше пример будет работать с вашими маршрутами верхнего уровня, такими как /books, что позволяет легко пропустить, но не работает на /books/pages.

person David Weldon    schedule 24.01.2014
comment
До перехода на железный роутер именно так я управлял статическими файлами. Но теперь, когда мое приложение становится многостраничным, я перешел на iron-router. Железный маршрутизатор воспринимает запрос, приходящий для /images/kitten.png, как еще один маршрут и выдает 404, когда не находит его. Поэтому мой вопрос заключается в том, как серверировать любой статический контент после движения. - person Goje87; 25.01.2014
comment
Тогда что-то не так с настройкой iron-router. Не видя всей конфигурации, я не могу сказать, что это такое, но вы можете попробовать удалить все свои маршруты и добавлять их по одному, пока не найдете проблему. - person David Weldon; 25.01.2014
comment
Я пытаюсь использовать концепцию, упомянутую в документе по железному маршрутизатору. Других маршрутов у меня пока нет. Нет даже маршрутизации на стороне клиента. - person Goje87; 25.01.2014
comment
Тогда, возможно, это другой пакет. Может быть полезно отладить проблему в обратном порядке — начните с пустого проекта и добавляйте код и пакеты, пока не увидите, что он сломается. Я уверен, что вы обнаружите проблему, если будете работать над ней систематически. - person David Weldon; 25.01.2014
comment
Хорошо, нет, я думаю, что это правильное поведение. После того, как ветка компоновщика попала, public компилируется в папку с манифестом: program.json с хэшами, местоположениями и т. д., так что файлы, добавленные ПОСЛЕ развертывания, больше не доступны динамически. - person MrMowgli; 17.07.2014
comment
Мех. Это был бы правильный ответ, если бы в железном маршрутизаторе не было ошибки, которая мешает ему работать должным образом. По состоянию на 3 сентября 2015 года с ним все еще есть проблемы. - person async; 03.09.2015

Вероятно, вам просто нужно убедиться, что маршрут находится в общей области, видимой как на клиенте, так и на сервере (этот маршрут фактически выполняется на сервере), и указать where: 'server'. Кроме того, нам нужно загрузить фактический файл с диска, что означает, что нам нужен фактический путь на сервере к файлу, и нам нужно загрузить «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);
    }
  });
});

Пара замечаний: вам, вероятно, следует переместить фактический код загрузки в функцию только для сервера и вместо этого вызвать ее, передав ответ функции.

Вы также должны выполнить некоторую проверку пути, чтобы никому не позволять произвольно загружать файлы на ваш сервер.

Кроме того, это явная установка типа контента, что вы, вероятно, захотите сделать для изображений, но, возможно, не для других типов контента. Для общего типа вы можете установить его на application/octet-stream

Конечно, как уже упоминалось, если ваша единственная цель — иметь некоторый статический контент, доступный во время развертывания, вы должны просто использовать каталог /public.

person MrMowgli    schedule 17.07.2014

Это ошибка в железном маршрутизаторе, которая, по их словам, исправлена, но я все еще сталкиваюсь с проблемой, и другие сообщали об этой проблеме с github, что это все еще проблема.

Изменить: кажется, что это работает для файлов, которые находятся непосредственно в /public, но не для файлов в папках внутри /public.

person foobarbecue    schedule 16.04.2015
comment
У меня есть файлы jpg в /public/images/ и я использую ‹img src=/images/whatever.jpg›, который работает. - person dpatte; 27.05.2018