如何禁用 i18next translation.json 文件的缓存?

Posted

技术标签:

【中文标题】如何禁用 i18next translation.json 文件的缓存?【英文标题】:How to disable caching for i18next translation.json files? 【发布时间】:2017-07-07 14:08:59 【问题描述】:

我在 IIS 上运行单页应用程序,并在我的应用程序中使用 i18next 库进行翻译。问题是,有时当我向我的 translation.json 文件添加新关键字并点击刷新时,浏览器仍然使用旧缓存的翻译文件,这导致用户看到添加的关键字但看不到翻译。例如。如果我添加关键字"somekey": "Some text here...",则将显示somekey 而不是指定的文本。

因为我的 translation.json 文件位于一个名为 locales 的文件夹中,如下所示:

locales
    en
      translation.json

我尝试在 web.config 中添加以下设置:

<location path="locales">
  <system.webServer>
    <staticContent>
      <clientCache cacheControlMode="DisableCache" />
    </staticContent>
  </system.webServer>
</location>

但是,当我使用 Chrome 开发人员工具查看网络流量时,我注意到 translation.json 文件仍然来自缓存并且缺少 Cache-Control: no-cache 标头。为什么这不起作用?禁用文件缓存的正确方法是什么?

编辑:刚刚再次检查了该站点,似乎translation.json 文件现在具有Cache-Control: no-cache 标头,并且实际上每次我刷新页面时都会从服务器检索它。在这一点上,我认为这个问题可能与我们的发布过程和未应用的配置更改有关。不过不确定。

【问题讨论】:

【参考方案1】:

这实际上比看起来更棘手。 我假设您正在使用角度翻译模块。

我在加载 json 文件的地方做了缓存破坏:

$translateProvider.useLoader('$translatePartialLoader', 
        urlTemplate: 'AppScripts/i18n/part-lang.json' + '?cb=' + (new Date()).getTime()
    );

这样它就永远不会缓存语言文件,并且会在每次请求时加载新的语言文件(不刷新页面或清除缓存)。

Web 配置设置被完全忽略,我相信是因为插件使用 ajax 调用加载文件的方式。 此外,无法使用 .net 捆绑来缩小 json 文件,因为压缩时密钥会发生变化,因此您将使用 "abc": "First Name" 代替 "MAIN.FIRSTNAME": "First Name" 和由于视图具有原始名称,因此无法正常工作。

如果您保留一个版本,您也可以使用该版本,仅在发布新版本时破坏缓存,例如

    + '?v=' + myVersionVar

而不是使用当前时间戳,它总是会在每次请求时加载文件。

【讨论】:

【参考方案2】:

我在使用组合 SPA + i18next + IIS 时遇到过同样的情况,并注意到有时 json 文件没有更新。

这在某些时候变得奇怪的主要原因是,自从第一次下载文件以来,您很有可能在文件已经被 Google Chrome 缓存之后更改了 IIS 的 web.config 设置没有任何Cache-Control 标头。

原因

json 文件没有显示 Cache-Control: no-cache 标头,因此在 304 - Not Modified 响应之后,它开始使用谷歌浏览器的本地磁盘缓存。

解决方案

解决了

1) 在网络选项卡中清理谷歌浏览器的缓存(清除所有缓存也可以)

2) 将 web.config 文件放置在 /locales/ 文件夹中,并使用以下 staticContent 规则和 location 而不指定 path 属性:

<?xml version="1.0" encoding="utf-8"?>
    <configuration>
        <location>
            <system.webServer>
                <staticContent>
                    <clientCache cacheControlMode="DisableCache" />
                </staticContent>
            </system.webServer>
        </location>
    </configuration>

正如the docs 关于&lt;location&gt; 标签所述:

path 属性

使用缺少path 属性的&lt;location&gt; 应用 配置设置到当前目录和所有子目录 目录。


在这种情况下,我在/locales/ 文件夹中专门应用了该规则,旨在不干扰网站上其他静态内容的缓存,例如图像、javascript 文件等。预期的行为可能会有所不同您的解决方案的需求。

【讨论】:

【参考方案3】:

我遇到了类似的问题,我需要在每次构建后重新检索翻译文件。我发现的一个解决方案是,首先,添加一个插件,允许 webpack 构建哈希在运行时可用(将其添加到 webpack.config.js 文件中):

webpack.ExtendedAPIPlugin()

这将允许您在应用程序的任何位置声明哈希

const hash = __webpack_hash__;

然后,在您的 i18next.init() 的后端部分,我将哈希作为参数添加到请求中。

`/locales/.json/hash=$hash`

这样,每次新构建后哈希值都会有所不同,并且在构建后的第一个请求中,将检索最新的翻译文件,从而阻止它使用缓存。

【讨论】:

【参考方案4】:

简单配置

我正在使用i18next-http-backend 处理XHR 请求。

...
import  initReactI18next  from 'react-i18next';
import Backend from 'i18next-http-backend';

i18next
    .use(Backend)
    .use(initReactI18next)
    .init(
        backend: 
            loadPath: '/content/locales/lng.json',
            requestOptions: 
                cache: 'no-store',
            ,
        ,
        ...
);

MDN

无商店

响应可能不会存储在任何缓存中。请注意,这不会阻止返回有效的预先存在的缓存响应。客户端可以设置 max-age=0 也清除现有的缓存响应,因为这会强制缓存与服务器重新验证(与 no-store 一起使用时没有其他指令有影响)。

【讨论】:

【参考方案5】:

感谢@alx,在我的 grunt 构建中使用了以下内容并替换了 version_number。

$translateProvider.useStaticFilesLoader(
    prefix: 'locale/lang_',
    suffix: '.json?cd=version_number'    );

【讨论】:

【参考方案6】:

如果我们在部署应用程序时启用捆绑会怎么样。 如下所示。

#if DEBUG
    BundleTable.EnableOptimizations = false;
#else
    BundleTable.EnableOptimizations = true;
#endif

【讨论】:

以上是关于如何禁用 i18next translation.json 文件的缓存?的主要内容,如果未能解决你的问题,请参考以下文章

i18next 显示键而不是值

如何使用 i18next?翻译问题

Rails i18n如何获取某个键的所有值?

ngx-translate 与 i18n 的区别

如何在 React Native 中导入 i18next?

如何使用钩子在反应 i18next 中修复“未指定回退 UI”