有这样一个场景:对于一个默认语言下存在的图像(图像数量在 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 不就好了
|
5
lisongeee 2022-09-06 19:05:16 +08:00
|