从后端到JavaScript共享本地化字符串

Share localization strings from backend to JavaScript

本文关键字:本地化 字符串 共享 JavaScript 后端      更新时间:2023-09-26

考虑一个带有两个JavaScript文件的JSP应用程序。后端是完全本地化的,使用几个.properties文件,每种语言一个。呈现的HTML包含正确语言的字符串——所有这些都是常见的东西,而且效果很好。

然而,现在我不时需要在JavaScript资源中使用一些本地化的字符串。假设例如:

function foo() {
  alert('This string should be localized!');
}

注意,这在某种程度上类似于从JavaScript引用一些AJAX端点的需要,反向JS路由器很好地解决了这个问题。然而,这里的关键区别在于,后端不使用路由器,而是使用字符串

我已经想出了几种方法,但似乎都不够好。

参数

呈现代码以调用foo()的JSP将获取字符串:

foo('<%= localize("alert.text") %>');
function foo(alertText) {
  alert(alertText);
}

优点:有效。缺点:方法签名过于臃肿。

原型

JSP用字符串呈现一个隐藏的跨度,JS获取它:

<span id="prototype" class="hidden">This string should be localized!</span>
function foo() {
  alert($('#prototype').text());
}

优点:方法签名不再臃肿。缺点:必须确保隐藏的<span>始终存在。

AJAX

有一个端点通过字符串的键来定位字符串,JS调用它。(代码是近似的。)

function foo() {
  $.ajax({ url : '/ajax/localize', data : { key : 'alert.text' } })
      .done(function(result) {
          alert(result);
      } );
}

优点:服务器可以完全控制本地化结果。缺点:每个本地化字符串一个HTTP调用!任何AJAX调用失败,逻辑就会中断。

这可以通过同时获得多个字符串来改进,但rountrip问题是一个重要的问题。

共享属性文件

包含当前语言的属性文件只是作为页面上的附加JS资源公开。

<script src="/locales/en.js" /> // brings in the i18n object
function foo() {
  alert(i18n.alert.text);
}

优点:快速可靠。缺点:所有的字符串都被拉入-还有那些我们不需要或不想向用户公开的字符串。

这可以通过为JS保留一组单独的字符串来改进,但这违反了DRY原则。

现在怎么办

就这样,这就是我的想法。他们都不理想,都有自己的问题。我目前正在使用前两种方法,结果喜忧参半。还有其他选择吗?

您的共享属性文件是您建议的4个想法中比较整洁的解决方案。我使用的一个名为Silversstripe的流行CMS实际上也做了同样的事情,加载一个本地化的JS文件,将字符串添加到字典中,允许使用一个通用的API来检索字符串。

评论中提出的一点是关于为特定视图包含本地化字符串。虽然在每次本地化有数千个字符串(总计超过几百KB)的特定情况下,这可能会有一些用途,但也可能有点不必要。

客户端

根据您同时加载的其他JS资源的数量,您可能不希望每个视图都有另一个请求,只为该区域设置添加几个字符串。每个视图的本地化都需要单独请求,这可能会有点低效。在一个请求中为浏览器提供所有本地化,并让它只从缓存中读取每个视图。

浏览器缓存完整的区域设置字符串集合可以带来更好的用户体验,更快的页面加载时间,每个视图只需减少一个请求。对于移动用户来说,这可能非常有帮助,因为即使移动互联网速度更快,也不是每个请求都像闪电一样快。

服务器端

如果按照注释中建议的方法,让一个locale.asp文件动态生成JS语言环境字符串,那么每个用户将为服务器提供更多的工作。如果每个用户请求一次,情况不会那么糟糕,但如果是按视图请求,则可能会开始增加。

如果用户查看了5个不同的页面,即服务器执行JSP的5次,构建特定视图的数据。虽然您的代码可能是基本的if语句,并从文件系统加载一些文件,但执行该代码仍有开销。虽然这可能不是问题,比如说每分钟10个请求,但可能会导致每分钟1000个请求的问题。

同样,额外的开销可能很小,但这根本没有必要,除非你真的想要很多小的HTTP请求,而不是几个大的HTTP请求和少量的浏览器缓存。

其他想法

虽然这听起来可能是过早的优化,但我认为这是一件简单而重要的事情。我们不知道你是有5个用户还是5000个,你的用户是看到5个不同的视图还是500个,你是否会有很多/任何移动用户,你想支持多少个区域设置,每个区域设置有多少不同的字符串。

正因为如此,我认为最好能更全面地了解每个视图下载区域设置字符串的选择