javascript - ExpressJS router normalizedcanonical urls - Stack Overflow

I'm after normalizedcanonical urls for SPA with ExpressJS server. Although it is SPA that is back

I'm after normalized/canonical urls for SPA with ExpressJS server.

Although it is SPA that is backed up by server side router - templates can differ a bit for app urls. One of the differences is <link rel="canonical" href="{{ originalPath }}"> tag. Not the relevant detail but explains the context of the question. I expect that there will be only one URL that responds with 200, its variations are redirected to it with 301/302 (works for living humans and search engines).

I would like to make the urls case-sensitive and strict (no extra slash), similarly to Router options, but non-canonical urls (that differ in case or extra slash) should do 301/302 redirect to canonical url instead of 404.

In most apps I just want to force the urls for * routes to be lower-cased (with the exception of queries), with no extra slashes. I.e. app.all('*', ...), and the redirects are:

/Foo/Bar/ -> /foo/bar
/foo/Bar?Baz -> /foo/bar?Baz

But there may be exceptions if the routes are defined explicitly. For example, there are camel-cased routes:

possiblyNestedRouter.route('/somePath')...
possiblyNestedRouter.route('/anotherPath/:Param')...

And all non-canonical urls should be redirected to canonical (parameter case is left intact):

/somepath/ -> /somePath
/anotherpath/FOO -> /anotherPath/FOO

The logic behind canonical urls is quite straightforward, so it is strange that I couldn't find anything on this topic regarding ExpressJS.

What is the best way to do this? Are there middlewares already that can help?

I'm after normalized/canonical urls for SPA with ExpressJS server.

Although it is SPA that is backed up by server side router - templates can differ a bit for app urls. One of the differences is <link rel="canonical" href="https://example.{{ originalPath }}"> tag. Not the relevant detail but explains the context of the question. I expect that there will be only one URL that responds with 200, its variations are redirected to it with 301/302 (works for living humans and search engines).

I would like to make the urls case-sensitive and strict (no extra slash), similarly to Router options, but non-canonical urls (that differ in case or extra slash) should do 301/302 redirect to canonical url instead of 404.

In most apps I just want to force the urls for * routes to be lower-cased (with the exception of queries), with no extra slashes. I.e. app.all('*', ...), and the redirects are:

/Foo/Bar/ -> /foo/bar
/foo/Bar?Baz -> /foo/bar?Baz

But there may be exceptions if the routes are defined explicitly. For example, there are camel-cased routes:

possiblyNestedRouter.route('/somePath')...
possiblyNestedRouter.route('/anotherPath/:Param')...

And all non-canonical urls should be redirected to canonical (parameter case is left intact):

/somepath/ -> /somePath
/anotherpath/FOO -> /anotherPath/FOO

The logic behind canonical urls is quite straightforward, so it is strange that I couldn't find anything on this topic regarding ExpressJS.

What is the best way to do this? Are there middlewares already that can help?

Share Improve this question edited Aug 23, 2017 at 22:23 Estus Flask asked Feb 11, 2017 at 19:10 Estus FlaskEstus Flask 224k79 gold badges472 silver badges611 bronze badges 0
Add a ment  | 

3 Answers 3

Reset to default 4 +100

I have looked for npms, I could not find any, so this scratched my mind and I've coded a small task for express to do for each request, which seem to work fine. Please add this to your code.

var urls = {
  '/main' : '/main',
  '/anotherMain' : '/anotherMain'
}

app.use(function(req, res, next){

  var index = req.url.lastIndexOf('/');

  //We are checking to see if there is an extra slash first
  if(req.url[index+1] == null || req.url[index+1] == undefined || req.url[index+1] == '/'){
     //slashes are wrong
     res.send("please enter a correct url");
     res.end();
  }else{

      for(var item in urls){
         if(req.url != item && req.url.toUpperCase() == item.toUpperCase()){
           res.redirect(item);
           console.log("redirected");
           //redirected
         }else if (req.url == item) {
           console.log("correct url");
           next();
         }else{
           //url doesn't exist
         }
     }

  }
  next();

});

app.get('/main', function(req, res){
  res.render('mainpage');
});

app.get('/anotherMain', function(req, res){
  res.send("here here");
});

USAGE

All you have to do is, add your urls to urls object like done above with giving it the same key value. That's it. See how easy it is. Now all of your clients request will be redirected to the correct page case sensitively.

UPDATE

I have also made one for POST requests, I think it is pretty accurate, you should also give it a try. Ff you want a redirect when the user mixes up slashes, you need to write some regex for it. I didn't have time also my brain was fried so I made a simple one. You can change it however you like. Every web structure has its own set of rules.

var urlsPOST = {
  '/upload' : '/upload'
}

app.use(function(req, res, next){

  if(req.method == 'POST'){

    var index = req.url.lastIndexOf('/');

    if(req.url[index+1] == null || req.url[index+1] == undefined || req.url[index+1] == '/'){

       //slashes are wrong
       res.sendStatus(400);
       res.end();
       return false;

    }else{

      for(var item in urlsPOST){
          if(req.url != item && req.url.toUpperCase() == item.toUpperCase()){
            res.redirect(307, item);
            res.end();
            return false;
            //redirected

          }else if (req.url == item) {
            console.log("correct url");
            next();

          }else{
            res.sendStatus(404).send("invalid URL");
            return false;
            //url doesn't exist
          }
      }
    }
  }
  next();
});

You probably want to write your own middleware for this, something along the lines of this:

app.set('case sensitive routing', true);

/* all existing routes here */

app.use(function(req, res, next) {
  var url = find_correct_url(req.url); // special urls only
  if(url){
    res.redirect(url); // redirect to special url
  }else if(req.url.toLowerCase() !=== req.url){
    res.redirect(req.url.toLowerCase()); // lets try the lower case version
  }else{
    next(); // url is not special, and is already lower case
  };
});

Now keep in mind this middleware can be placed after all of your current routes, so that if it does not match an existing route you can try to look up what it should be. If you are using case insensitive route matching you would want to do this before your routes.

Using the same code as @user8377060 just with a regex instead.

  // an array of all my urls
  var urls = [
    '/main',
    '/anotherMain'
  ]

  app.use(function(req, res, next){

    var index = req.url.lastIndexOf('/');

    //We are checking to see if there is an extra slash first
    if(req.url[index+1] == null || req.url[index+1] == undefined || req.url[index+1] == '/'){
     //slashes are wrong
     res.send("please enter a correct url");
     res.end();
    }else{

      for(var item in urls){
         var currentUrl = new RegExp(item, 'i');

         if(req.url != item && currentUrl.test(item)){
           res.redirect(item);
           console.log("redirected");
           //redirected
         }else if (req.url == item) {
           console.log("correct url");
           next();
         }else{
           //url doesn't exist
         }
     }

    }
    next();

  });

发布者:admin,转转请注明出处:http://www.yc00.com/questions/1744377294a4571249.html

相关推荐

  • javascript - ExpressJS router normalizedcanonical urls - Stack Overflow

    I'm after normalizedcanonical urls for SPA with ExpressJS server. Although it is SPA that is back

    7天前
    20

发表回复

评论列表(0条)

  • 暂无评论

联系我们

400-800-8888

在线咨询: QQ交谈

邮件:admin@example.com

工作时间:周一至周五,9:30-18:30,节假日休息

关注微信