【问题标题】:Express routing non ascii characters (Farsi)快速路由非 ascii 字符(波斯语)
【发布时间】:2016-11-26 03:05:24
【问题描述】:

我正在尝试使用这条路线http://localhost:3030/api/words/عشق 在我的快递应用程序中,所以我可以匹配字典中的单词。

浏览器将 url 更改为 http://localhost:3030/api/words/%D8%B9%D8%B4%D9%82,但我编写了一个小型中间件,在将其传递给路由之前将其转换回原始版本。在路线中,我有正则表达式来检查包含波斯语/波斯语字符的 unicode 字符。

不确定发生了什么,因为中间件打印/words/عشق,如果我删除正则表达式规则,路由也会打印/words/عشق。为什么快递不匹配这个? express 不使用 req.url 来确定路线吗?

    /** Get word be string **/
    api.get('/:word(^([\\u0600-\\u06FF]+\\s?)+$)', (req, res, next) =>{
            console.log("persian version " + req.url);
            res.send(req.params);
});


 /** Url encoder middleware **/ 
function urlencoder(req, res, next) {
      req.url = decodeURIComponent(req.url); 
      console.log("Middleware " + req.url);
      next();
}

【问题讨论】:

  • 我认为它不使用它。这样重写也感觉不对。为什么不在你的 api.get 函数中解码它,然后再查找它?
  • 因为如果没有预解码,我无法使用正则表达式匹配 url。
  • 它实际上应该可以修改 req.url - 根据我对 Express 路由器实际所做的阅读。 api的定义是什么,中间件堆栈中的api和urlencoder在哪里?
  • 是的,使用中间件调整 req.url 的值确实有效——中间件链中该点之后的所有路由都是基于修改后的 URL 进行路由。
  • 我在 cors 中间件之后和正文解析器之前添加中间件。甚至关闭了其他中间件,但似乎不起作用。 api 是一个快速路由器,用于将路由分组到不同的类中。

标签: javascript node.js express non-ascii-characters unicode-string


【解决方案1】:

我认为将路由路径转换为正则表达式的代码已经在正则表达式前面加上了一个锚 (^),所以你不应该在你的代码中使用额外的。

这似乎有效:

let unescape = require('querystring').unescape;

api.use((req, res, next) => {
  req.url = unescape(req.url);
  next();
});

api.get('/:word(([\\u0600-\\u06FF]+\\s?)+$)', (req, res) => {
  console.log("persian version " + req.url);
  res.send(req.params);
});

【讨论】:

  • 我认为路由器不会自动在正则表达式前面加上^,而是我认为这是对^ 含义的误解。 ^ 表示“字符串开头”或“行开头”,具体取决于多行标志。因此,搜索该字符串的开头位于中间的字符串将不会匹配任何可能的字符串(请注意,根据定义,URL 是单行,因此对于 ^ 的含义只能有一种解释)
  • @slebetman 我想我们的意思是一样的:D 像/:word 这样的路由路径将被转换为以^\/ 开头的正则表达式(后跟参数匹配)。因此,添加另一个^ 将永远无法匹配路径的开头。
  • @robertklep 不,我们的意思不一样。他的正则表达式是 ':word^...' - 他试图匹配一个在任何字母数字字符之后开始的字符串。这显然永远不会匹配任何字符串,因为“开始”的定义意味着它之前不能有任何东西。这就像有人试图匹配正则表达式'.*$hello'——一个在它结束之前结束的字符串就像一个在它开始之后开始的字符串一样愚蠢
  • @slebetman :word 不是要在 URL 中匹配的文字字符串,它是一个占位符,它被 Express 转换为特定的正则表达式模式(我认为匹配一系列 alnum 字符)。您可以使用:word(REGEX) 添加自己的正则表达式模式来覆盖与该占位符匹配的模式
  • @robertklep:是的,但^ 也不是文字字符串匹配。它的意思是“此字符之前没有字符” - 也称为“字符串开头”。因此,如果 :word 匹配某些内容,则在其后面加上 ^ 意味着 ^ 不再是字符串的开头,因此正则表达式不匹配任何可能的字符串。原始正则表达式可以工作的唯一可能方式是:word 表示空字符串,但这不是它通常的意思。我假设它表示任何字母数字字符而不是空字符串(正如我在上面的评论中所说)
猜你喜欢
  • 1970-01-01
  • 2021-12-18
  • 2012-01-13
  • 1970-01-01
  • 1970-01-01
  • 2018-10-20
  • 1970-01-01
  • 1970-01-01
  • 2016-12-26
相关资源
最近更新 更多