【问题标题】:Node express api routes for multilingual directory like url用于多语言目录(如 url)的 Node express api 路由
【发布时间】:2017-10-17 11:58:03
【问题描述】:

有没有人知道一个例子或者可以在这里解释 node.js 和 express 如何为多语言站点进行路由?我正在使用 i18n-node 进行翻译和文件夹,如路由( /es/、/de/ 等)用于不同语言。这都是静态路由,但我也有像 apiRoutes.route('/user/profile') 这样的路由,在开始时使用 'app' ( app.get('/app/user/ profile') 所以请在你的回答中考虑这一点,所以不是必要的途径:app.get('/es/app/user/profile')

现在有 15 条这样的路线:

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

如何为以下路线设置:

app.get('/es/terms', function(req, res) {
    res.render('terms',{
   ...
    });
});
  1. 我是否应该复制此路线并添加例如语言环境 每个喜欢:

    app.get('/es/terms', function(req, res) {
        res.render('terms',{
        ...
         });
     });
    
  2. 或者应该这样做:

     if cookie['lang'] && cookie['lang'] is in locales 
        // then redirect to /:lang/terms
      else
        // show default language in /terms
     if req.headers["accept-language"] && req.headers["accept-language"] 
        // then redirect to /:lang/terms
     else 
        //show default language in /terms
    
  3. 或者我应该采用另一种方法来处理这个问题,它遵循良好的做法或更好地尊重标准?

  4. 米罗的回答: How can I get the browser language in node.js (express.js)? 说我应该使用 app.all('*', ...

这就是我所需要的吗?,..仍然,它可能有语法错误,或者我对这两部分不太理解

    var rxLocal = /^\/(de|en)/i;
    ...
    app.get(/\/(de|en)\/login/i, routes.login);

提前致谢

【问题讨论】:

  • 通过 HTTP 管理 i18n 的常规方法是使用为此设计的标头 Accept-Language。否则,@patrick-hund 提议似乎是处理路线的最佳方式。您可以添加一个中间件来为您的所有路由执行一些通用过程。
  • “所有路由的通用流程”是什么意思......任何特定的中间件? @Techniv
  • 用语言环境数据丰富requestresponse 对象,为渲染引擎设置语言环境数据等。参见app.use()

标签: node.js express i18n-node


【解决方案1】:

你需要考虑两件事:

1。如何获取本地:

接受语言

HTTP 协议定义了Accept-Language header 来管理本地。这是一种标准化的方法。可以通过req.acceptsLanguages express 方法访问。

  • +归一化
  • +浏览器原生支持
  • -最终用户不容易绕过

路径/Cookies

您可以从路径中获取本地信息。在 express 中,可以使用 /:local/rest/of/path 之类的参数模式,并使用 req.param 方法在请求对象中检索。

您还可以使用 req.cookies 属性从 cookie 中获取信息(不要忘记设置它)。

两者

为了增加用户体验,您可以混合使用这两种方法。例如,从浏览器发送的 HTTP 标头中获取默认语言,但允许用户在您的应用程序中覆盖它并将此参数存储在 cookie 中。

2。使用本地:

每种获取本地的方法都可以从不同的方式使用。我会 以它们中的随机为例,但它们都是兼容的。

顶级配置。

如果您使用模板引擎并且您的控制器可以与本地无关。您可以使用middleware 获取本地信息并配置渲染引擎。

app.use('/:local' (req, res, next) => {
  let localKey = req.param('local');
  res.locals = // Some ingenious method to get the locales from localKey

  next();
}

检查res.locals 和您的引擎文档。

在控制器中使用它。

如果本地是控制器进程的一部分。可以直接获取控制器中的值。

如果您使用复杂的方法来确定本地的最终值,您还可以使用中间件来确定该值并用它来丰富请求。

app.use((req, res, next) => {
  let local = req.cookies.local;
  if(!local) local = req.acceptsLanguages();
  if(!local) local = 'en-US';
  req.local = local;
}

两者

您也可以同时使用这两种方法。这取决于你需要什么。找到获得可维护代码并避免复制您的用例的最佳方法。

当你在 wwitch 影响控制器的地方使用中间时,一定要在你的路由之前声明它们。

【讨论】:

  • 这在我看来是一个很好的实现和对我需求的考虑,尽管让我把两者都付诸实践,我会回来接受一个回答。谢谢@Techniv
【解决方案2】:

您可以使用路由参数从 URL 中获取语言环境,如下所示:

app.get('/:lang/terms', function (req, res) {
    if (req.params === 'es') {
        res.send('¡Hola!');
    else {
        res.send('Hi!');
    }
});

冒号告诉 Express 在req.params.lang 的路径的第一个斜杠之间放置任何内容。 详情请见express routing documentation

【讨论】:

  • 我以前试过这个。有了这个,我将有一个路由 "/es/terms" , /de/terms ...但是当有人去 "/terms 并且我想向他们展示(重定向)到特定的 "用户代理或 cookie 语言“他们有? ...我应该为此创建另一条路线吗?
  • 是的,在这种情况下我会重定向
  • 您如何看待 Techniv 的评论? “用 app.use(); 丰富请求或响应;”如果你不介意我问的话。我正在阅读这两种想法,因为我发现两种方法都是正确的。如果其他人想添加一些东西,我也会给时间。
  • 使用中间件的选择和你用什么做取决于你真正需要用本地做什么。如果您的控制器从数据库获取数据并使用支持语言环境(如 EJS)的引擎呈现模板,则此控制器可以与本地无关,您可以使用中间件来配置引擎。如果在控制器进程中使用本地,则需要将其传递给控制器​​。
  • 这两种情况都可以使用@PatrickHund 的path 方法或header 方法。我会尝试在答案中综合这一点。
猜你喜欢
  • 1970-01-01
  • 2011-01-09
  • 1970-01-01
  • 2020-03-09
  • 2022-01-07
  • 1970-01-01
  • 2019-06-16
  • 1970-01-01
  • 2014-05-17
相关资源
最近更新 更多