Подтвердить что ты не робот

Перенаправить все конечные косые черты глобально в экспресс

Я использую Node.js и Express, и у меня есть следующая маршрутизация:

app.get('/', function(req,res){
    locals.date = new Date().toLocaleDateString();

    res.render('home.ejs', locals);
});

function lessonsRouter (req, res, next)
{
    var lesson = req.params.lesson;
    res.render('lessons/' + lesson + '.ejs', locals_lessons);
}

app.get('/lessons/:lesson*', lessonsRouter);


function viewsRouter (req, res, next)
{
    var controllerName = req.params.controllerName;
    res.render(controllerName + '.ejs', locals_lessons);
}
app.get('/:controllerName', viewsRouter);

У меня есть виджет Disqus на моих уроках, и я заметил странное поведение, которое при переходе на myapp.com/lessons и myapp.com/lessons/ получилось два разных (у них был комментарий, который я ранее добавил в Disqus, а другой - не комментарий).

Есть ли способ "канонизировать" все мои URL-адреса, чтобы они не были связаны с косой чертой? Я попытался добавить флаг strict routing, чтобы выразить, но результаты были теми же

Спасибо

4b9b3361

Ответ 1

Попробуйте добавить для этого промежуточное программное обеспечение,

app.use(function(req, res, next) {
   if(req.url.substr(-1) == '/' && req.url.length > 1)
       res.redirect(301, req.url.slice(0, -1));
   else
       next();
});

Ответ 2

Ответ Tolga Akyüz вдохновляет, но не работает, если есть какие-либо символы после слэш. Например, http://example.com/api/?q=a перенаправляется на http://example.com/api вместо http://example.com/api?q=a.

Вот улучшенная версия предлагаемого промежуточного программного обеспечения, которое устраняет проблему, добавляя исходный запрос в конец URL-адреса назначения перенаправления:

app.use(function(req, res, next) {
    if (req.path.substr(-1) == '/' && req.path.length > 1) {
        var query = req.url.slice(req.path.length);
        res.redirect(301, req.path.slice(0, -1) + query);
    } else {
        next();
    }
});

Примечание. Как отмечено jamesk и указано в RFC 1738, конечная косая черта может быть опущена только тогда, когда после домена ничего не происходит. Следовательно, http://example.com?q=a является недопустимым URL-адресом, где http://example.com/?q=a является допустимым. В этом случае перенаправление не должно выполняться. К счастью, выражение req.path.length > 1 позаботится об этом. Например, с учетом url http://example.com/?q=a путь req.path равен /, и, таким образом, избегается перенаправление.

Ответ 3

Средство промежуточного связывания с соединительными линиями было разработано специально для этой потребности: https://npmjs.org/package/connect-slashes

Установите его с помощью:

$ npm install connect-slashes

Прочитайте полную документацию: https://github.com/avinoamr/connect-slashes

Ответ 4

Я добавляю этот ответ, потому что у меня было слишком много проблем с другими решениями.

router.use(function(req, res, next) {
    if (req.originalUrl != req.baseUrl + req.url) {
        res.redirect(301, req.baseUrl + req.url);
    }
    else
        next();
});

Это переведет:

/page ==> /page/
/page?query=value ==> /page/?query=value

Ответ 5

Ответы, приведенные выше, будут работать во многих случаях, но GET vars могут столкнуться с проблемами, и если вы ставите это внутри другого прямого промежуточного программного обеспечения, его зависимость от req.path вызовет проблему, и его зависимость от req.url также может иметь нежелательные побочные эффекты. Если вы ищете более плотное решение, это будет делать трюк:

// Redirect non trailing slash to trailing slash
app.use(function(req, res, next){
    // Find the query string
    var qsi = req.originalUrl.indexOf('?');
    // Get the path
    var path = req.originalUrl;
    if(qsi > -1) path = path.substr(0, qsi);
    // Continue if the path is good or it a static resource
    if(path.substr(-1) === '/' || ~path.indexOf('.')) return next();
    // Save just the query string
    var qs = '';
    if(qsi > -1) qs = req.originalUrl.substr(qsi);
    // Save redirect path
    var redirect = path + '/' + qs;
    // Redirect client
    res.redirect(301, redirect);

    console.log('301 redirected ' + req.originalUrl + ' to ' + redirect);
});

Он всегда доволен переменными GET и не будет ломаться, если вы будете помещать его в промежуточное ПО.

Ответ 6

Один вкладыш:

router.get('\\S+\/$', function (req, res) {
  return res.redirect(301, req.path.slice(0, -1) + req.url.slice(req.path.length));
});

Это только уловит URL-адрес, который необходимо перенаправить, и игнорировать остальные.

Примеры результатов:

/         ==> /
/a        ==> /a
/a/       ==> /a
/a/b      ==> /a/b
/a/b/     ==> /a/b
/a/b/?c=d ==> /a/b?c=d