有这样一个场景:对于一个默认语言下存在的图像(图像数量在 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
没有 fr
和 ja
这两个语言对应的本地化图像。那求和计算就是: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 gwbw 2022-09-06 17:16:11 +08:00 如果让所有本地化图片都存在,是不是可以解决问题。比如跑一个批量初始化脚本,把所有不存在的本地化图片都塞一个默认语言的图片上去,命名还是本地化的名称。省得后面更新图片还要维护存在 / 不存在的状态。前提是能接受 8 * 4000 的图片存储成本 |
![]() | 3 debuggerx 2022-09-06 17:39:07 +08:00 设置下 img 的 onerror 时间,替换 src 成 fallback 的 url 不就好了 |
![]() |