Redirect all trailing slashes globally in express

后端 未结 7 1638
醉话见心
醉话见心 2020-11-28 23:40

I am using Node.js and Express and I have the following routing :

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

    r         


        
相关标签:
7条回答
  • 2020-11-29 00:12

    The answers above will work in a lot of cases but GET vars can encounter issues and if you were to put that inside another express middleware its reliance on req.path will cause a problem and its reliance on req.url can also have unwanted side effects. If you're looking for a tighter solution this will do the trick:

    // 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's 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);
    });
    

    It's always happy with GET variables and won't break if you were to put it inside middleware.

    0 讨论(0)
  • 2020-11-29 00:15

    Try adding a middleware for that;

    app.use((req, res, next) => {
      const test = /\?[^]*\//.test(req.url);
      if (req.url.substr(-1) === '/' && req.url.length > 1 && !test)
        res.redirect(301, req.url.slice(0, -1));
      else
        next();
    });
    
    0 讨论(0)
  • 2020-11-29 00:17

    The answer by Tolga Akyüz is inspiring but doesn't work if there is any characters after the slash. For example http://example.com/api/?q=a is redirected to http://example.com/api instead of http://example.com/api?q=a.

    Here is an improved version of the proposed middleware that fix the problem by adding the original query to the end of the redirect destination 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();
        }
    });
    

    Note: As noted by jamesk and stated in RFC 1738, the trailing slash can only be omitted when there is nothing after the domain. Therefore, http://example.com?q=a is an invalid url where http://example.com/?q=a is a valid one. In such case, no redirection should be done. Fortunately, the expression req.path.length > 1 takes care of that. For example, given the url http://example.com/?q=a, the path req.path equals to / and thus the redirection is avoided.

    0 讨论(0)
  • 2020-11-29 00:22

    The connect-slashes middleware was designed specifically for this need: https://npmjs.org/package/connect-slashes

    Install it with:

    $ npm install connect-slashes

    Read the full documentation: https://github.com/avinoamr/connect-slashes

    0 讨论(0)
  • 2020-11-29 00:23
    /**
     * @param {express.Request} req
     * @param {express.Response} res
     * @param {express.NextFunction} next
     * @return {void}
     */
    function checkTrailingSlash(req, res, next) {
        if (req.path.slice(req.path.length-1) !== '/') {
            res.redirect(301, req.path + '/' + req.url.slice(req.path.length));
        } else {
            next();
        }
    }
      
    app.use(checkTrailingSlash);
    

    Example results:

    /         ==> /
    /a        ==> /a/
    /a/       ==> /a/
    /a/b      ==> /a/b/
    /a/b/     ==> /a/b/
    /a/b?c=d  ==> /a/b/?c=d
    /a/b/?c=d ==> /a/b/?c=d
    
    0 讨论(0)
  • 2020-11-29 00:34

    One liner:

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

    This will only catch the url's that need to be redirected, and ignore the others.

    Example results:

    /         ==> /
    /a        ==> /a
    /a/       ==> /a
    /a/b      ==> /a/b
    /a/b/     ==> /a/b
    /a/b/?c=d ==> /a/b?c=d
    
    0 讨论(0)
提交回复
热议问题