V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
yin1999
V2EX  ›  程序员

怎样通过可以用 JSON 表示的数据结构来存储本地化内容的语言回退状态

  •  
  •   yin1999 ·
    yin1999 · 2022-09-06 17:04:04 +08:00 · 1158 次点击
    这是一个创建于 791 天前的主题,其中的信息可能已经有所发展或是发生改变。

    场景

    有这样一个场景:对于一个默认语言下存在的图像(图像数量在 4000 张左右),其 URL 类似这样:/en-US/docs/Web/hello.png。而网站会有多个本地化的语言(大概 8 个左右),每一种语言都会引用本地化的图像,与上面的图像对应的本地化图像的 URL 类似这样:/zh-CN/docs/Web/hello.png。但不一定每一个语言都存在本地化的图像。

    存在的问题

    所以就有一个问题:存储默认语言下的图像在哪些本地化语言中存在(或不存在),在通过 Web 访问时,若图像并没有被本地化(在本地化语言中不存在),则回退到默认语言。

    这些文件通过 AWS S3 和 CloudFront 部署,所以只能在 Lambda@Edge 上解决这个问题(将上面图像的本地化状态存储在 JSON 中,通过 JavaScript 去处理上述的逻辑)

    想到的解决方案

    将每一种本地化语言都标记成 32 位整数中的一个二进制位,类似这样:

    语言
    zh-CN 1
    fr 2
    ja 4
    ... .

    对于每一张默认语言下的图像,找出对应的图像在哪些本地化语言下不存在,将这些不存在的语言对应的二进制值进行求和。例如,图像 /en-US/docs/Web/hello.png 没有 frja 这两个语言对应的本地化图像。那求和计算就是:2+4=6 。这样就可以直接通过键值对存储在 JSON 里面:

    {
      "docs/Web/hello.png": 6,
      // ...
    }
    

    在 Lambda@Edge 的 JavaScript 运行环境下就可以直接导入这个 JSON ,并通过按位与运算判断本地化图像是否不存在:

    const notExist = require('notExist.json');
    const bitMask = {
      "zh-CN": 1,
      "fr": 2,
      "ja": 4,
    }
    
    // path: /en-US/docs/Web/hello.png
    let path = request.uri;
    const uriParts = path.split("/");
    const locale = uriParts[1];
    const pathWithoutLocale = uriParts.slice(2).join("/");
    
    if (
      locale !== "en-US" &&
      notExist[pathWithoutLocale] &&
      (notExist[pathWithoutLocale] & bitMask[locale]) !== 0
    ) {
      // 不存在(但存在于默认语言中),使用默认语言下的图像
      path = `/en-US/${pathWithoutLocale}`;
    }
    

    有什么更合适的思路不?

    第 1 条附言  ·  350 天前
    最后选择拷贝文件解决,存储不值钱
    6 条回复    2022-09-06 19:29:54 +08:00
    gwbw
        1
    gwbw  
       2022-09-06 17:16:11 +08:00
    如果让所有本地化图片都存在,是不是可以解决问题。比如跑一个批量初始化脚本,把所有不存在的本地化图片都塞一个默认语言的图片上去,命名还是本地化的名称。省得后面更新图片还要维护存在 / 不存在的状态。前提是能接受 8 * 4000 的图片存储成本
    yin1999
        2
    yin1999  
    OP
       2022-09-06 17:22:50 +08:00
    @gwbw 更新图片不是问题,这个 JSON 文件在每天构建文档并部署到 S3 上时是会自动更新的。
    debuggerx
        3
    debuggerx  
       2022-09-06 17:39:07 +08:00
    设置下 img 的 onerror 时间,替换 src 成 fallback 的 url 不就好了
    debuggerx
        4
    debuggerx  
       2022-09-06 17:39:52 +08:00
    @debuggerx #3 时间 -> 事件
    yin1999
        6
    yin1999  
    OP
       2022-09-06 19:29:54 +08:00 via Android
    @debuggerx 不太方便用这个方法,有些图片会用于一些嵌入的代码示例,有的 js 代码示例会直接调用 fetch 方法。要通过前端处理的话,应该只能走 web worker 。
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   1295 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 21ms · UTC 23:31 · PVG 07:31 · LAX 15:31 · JFK 18:31
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.