如何禁用 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 关于<location>
标签所述:
path
属性使用缺少
path
属性的<location>
应用 配置设置到当前目录和所有子目录 目录。
在这种情况下,我在/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 文件的缓存?的主要内容,如果未能解决你的问题,请参考以下文章