【问题标题】:How to disable caching for i18next translation.json files?如何禁用 i18next translation.json 文件的缓存?
【发布时间】: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 标头,并且实际上每次我刷新页面时都会从服务器检索它。在这一点上,我认为这个问题可能与我们的发布过程和未应用的配置更改有关。不过不确定。

【问题讨论】:

    标签: json caching web-config cache-control i18next


    【解决方案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
              

              【讨论】:

                猜你喜欢
                • 1970-01-01
                • 2021-11-04
                • 1970-01-01
                • 2022-06-17
                • 2021-05-11
                • 1970-01-01
                • 1970-01-01
                • 2012-09-22
                • 1970-01-01
                相关资源
                最近更新 更多