nodejs Маршруты ExpressJS работают только для индекса

У меня есть маршруты в отдельной папке для expressjs. Настройка работает нормально для страницы «индекс», но не для каких-либо дополнительных маршрутов.

Это мой index.js в папке моих маршрутов.

 module.exports = function(db) {

    return {
        index: function(req, res, next) {
            res.send('index');
        }
    }
}

Это мой файл join.js в папке моих маршрутов.

 module.exports = function(db) {

    return {
        join: function(req, res, next) {
            res.send('join');
        }
    }
}

В моем app.js я определяю свои маршруты следующим образом:

          var routes = require('./routes')(db);
          app.get('/', routes.index);
          app.get('/join', routes.join);

Когда я иду к http://localhost:3000, но когда я иду к http://localhost:3000/join, я получаю Cannot GET /join

Если я определяю свой маршрут для соединения следующим образом:

 app.get('/join', function(req, res){
     res.send('join 2');
 });

Это работает.

Любая идея, что я делаю неправильно здесь?

Спасибо!


person dzm    schedule 03.04.2012    source источник


Ответы (5)


У меня была похожая проблема, но потом я вспомнил, что это все «просто javascript», и смог запутать ответ.

Если вы хотите, чтобы ваши маршруты были определены в нескольких файлах (вместо того, чтобы запихивать их все в один файл route/index.js), вы можете просто создать объект маршрутов хакерским способом (следующим образом):

var express = require('express')
  , routes = {
       index: require('./routes').index
     , events: require('./routes/events.js').events
  }
  , hbs = require('hbs');

ПРИМЕЧАНИЕ. Вам не нужны определения express и hbs (первая и последняя строки), я просто поместил их туда, чтобы дать вам небольшой контекст. Этот фрагмент кода взят непосредственно из верхней части моего файла app.js.

Обратите внимание на .index и .events, связанные с вызовами функций require(). Это ключ. Мой файл events.js имеет только один экспорт (события):

exports.events = function(req, res){
  console.log('in events');
  res.render('events', { events: events, title: "EVENTS" });
  console.log('events done');
};

Поскольку функция require(), по сути, захватывает файл и требует (импортирует) любые неприватные переменные (то есть те, которые прикреплены к специальному объекту exports) и предоставляет их файлу, содержащему вызов require(), я могу просто захватить конкретный функция, которую я требую из файла, который я включаю с вызовом require(). Если бы у меня было несколько экспортов, определенных в требуемом файле, я думаю, что мог бы получить их так (не проверял):

routes = {
    index: require('./routes').index
  , events: require('./routes/events.js').events
  , favorites: require('./routes/events.js').favorites
  , upcoming: require('./routes/events.js').upcoming
}

Я подозреваю, что это вызовет у кого-то с кучей nodeJS или MVC аневризму, если они прочитают ваш код (держу пари, что он будет включать один и тот же файл 3 раза, но я не совсем уверен). Может быть, лучше сделать:

routes = {
    index: require('./routes').index
  , events: require('./routes/events.js').events
  , favorites: require('./routes/favorites.js').favorites
  , upcoming: require('./routes/upcoming.js').upcoming
}

В противном случае, почему бы просто не засунуть их все в индекс? Хотя не совсем уверен, я только второй день работаю с Node и любыми связанными с ним технологиями...

Также, вероятно, поможет вам, если вы выберете оператор console.log сразу после ваших объявлений var:

console.log(routes);
person cmcculloh    schedule 10.04.2012
comment
+1, но потом вспомнил, что это всего лишь javascript, и смог запутать ответ. !! Шикарный ответ :) - person painotpi; 11.01.2013
comment
Модули кэшируются после первой загрузки nodejs.org/api/modules.html#modules_caching< /а> - person Asa Ayers; 05.09.2013

Причина, по которой файл route/index.js работает, а файл route/join.js — нет, заключается в правилах загрузки модулей Node. Ознакомьтесь с документацией по модулям/папкам как модулям.

Он говорит, что попытается загрузить эти файлы по порядку. package.json, index.js, index.node.

Вы можете изменить загружаемый файл, создав файл package.json в каталоге. Задайте для свойства main имя нового файла.

Пример того, как заставить маршруты работать так, как вы хотите, приведен в другом вопросе.

person Jason    schedule 21.04.2012

Я протестировал аналогичный сценарий, и он сработал для меня.

Я предполагаю, что ошибка, вероятно, в вашем файле route.js. Вы, вероятно, делаете:

routes.index = require('./index')(db);
routes.join = require('./join')(db);

Возможно, вы забыли вызвать метод для join, просто сделав require(./join). Просто предположение.

person mihai    schedule 04.04.2012

если ты просто скажешь

var routes = require('./routes')

По умолчанию node начнет поиск индексного файла (будь то index.js или index.node). Если вы хотите использовать свой файл соединения, вам нужно будет явно указать это:

var join = require('./routes/join')

Теперь я думаю, что join.join должен работать.

person user2393426    schedule 03.04.2014

Была аналогичная проблема.

Работал только мой маршрут "/". При попытке создать «/ about» я получаю ошибку 404.

Оказывается, когда я использовал экспресс-генератор, он написал:

app.use('/about', ...etc )

Вместо этого должно было быть:

app.all('/about', ...etc )

Я знаю, что это не та же самая проблема, но это для заблудших, которые ищут здесь тот же вопрос, что и проблема «работает только индекс ...».

person Ejnaren    schedule 06.09.2016