ExpressJS路由器规范化/规范化URL



我正在使用ExpressJS服务器为SPA寻找规范化/规范化的URL。

尽管SPA是由服务器端路由器备份的,但应用程序URL的模板可能会有所不同。区别之一是<link rel="canonical" href="https://example.com{{ originalPath }}">标签。不是相关的细节,而是解释了问题的背景。我预计只有一个URL会以200响应,其变体会以301/302重定向到它(适用于活人和搜索引擎)。

我想让url区分大小写并严格(没有额外的斜杠),类似于Router选项,但非规范url(大小写或额外的斜杠不同)应该重定向到规范url的301/302,而不是404。

在大多数应用程序中,我只想强制*路由的url大小写较低(查询除外),没有额外的斜杠。即app.all('*', ...),重定向为:

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

但是,如果路由是明确定义的,则可能会有例外。例如,有骆驼式路线:

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

所有非规范url都应该重定向到规范(参数情况保持不变):

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

规范url背后的逻辑非常简单,所以奇怪的是,我在这个主题上找不到任何关于ExpressJS的东西。

最好的方法是什么?已经有中间件可以提供帮助了吗?

我一直在寻找npms,但没有找到,所以这让我很头疼,我为express为每个请求编写了一个小任务,看起来很好。请将此添加到您的代码中。

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

用法

您所要做的就是,像上面所做的那样,将urls添加到urls对象中,并赋予其相同的键值。就是这样。看看它有多容易。现在,您所有的客户端请求都将被重定向到正确的页面,区分大小写

更新

我也为POST请求做了一个,我认为它非常准确,你也应该试一试。如果你想在用户混淆斜杠时重定向,你需要为它写一些regex。我没有时间,我的大脑也被炸了,所以我做了一个简单的重定向。你可以随意更改。每个web结构都有自己的一套规则。

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

您可能想为此编写自己的中间件,大致如下:

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

现在请记住,这个中间件可以放在所有当前路由之后,这样,如果它与现有路由不匹配,你可以尝试查找它应该是什么。如果你使用的是不区分大小写的路由匹配,你会想在路由之前这样做。

使用与@user8377060相同的代码只需使用regex。

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

最新更新