浏览器在 Azure 应用服务托管的根目录 index.html 上保留了令人困惑的 angular 应用缓存版本
Browser keep a confusing cached version of angular app on root index.html hosted with azure app service
我们目前在 Azure/App 服务上有 2 个版本的 Angular 应用程序来支持内部化。
托管在同一个地方但在不同的文件夹 /en 和 /fr。
我们的文件夹树看起来像这样
->
wwwroot/index.html
wwwroot/web.config
wwwroot/en/index.html
wwwroot/en/..
wwwroot/fr/index.html
wwwroot/fr/..
我们确实有一个 web.config 完美运行的重写规则。见下文:
<configuration>
<system.webServer>
<rewrite>
<rules>
<rule name="Angular Routes fr" stopProcessing="true">
<match url="fr/.*" />
<conditions logicalGrouping="MatchAll">
<add input="{REQUEST_FILENAME}" matchType="IsFile" negate="true" />
<add input="{REQUEST_FILENAME}" matchType="IsDirectory" negate="true" />
</conditions>
<action type="Rewrite" url="fr/" />
</rule>
<rule name="Angular Routes en" stopProcessing="true">
<match url="en/.*" />
<conditions logicalGrouping="MatchAll">
<add input="{REQUEST_FILENAME}" matchType="IsFile" negate="true" />
<add input="{REQUEST_FILENAME}" matchType="IsDirectory" negate="true" />
</conditions>
<action type="Rewrite" url="en/" />
</rule>
</rules>
</rewrite>
</system.webServer>
</configuration>
这是一个转折点;我们确实提供了根 index.html,以防用户导航到 www.app.com/*
而不是 www.app.com/en
。
在这种情况下,root index.html 被触发,我们 运行 一些 js 脚本根据本地存储语言使用 "window.location.href" 用户重定向。
出于某种原因,当我们从根 www.app.com
查询 url 时
浏览器 link 并将第一个版本缓存到此 url.
如果我们使用这样的资源查询 url www.app.com/en/*
浏览器 link 尽管域相同,但此路径的另一个版本。
问题是每次我们部署新版本时,只有任何资源的路径会被更新,例如:www.app.com/en/*
或 www.app.com/fr/*
但根 url www.app.com
坚持使用旧版本,永不更新。
如果用户使用 root url,它将被重定向到仅在内存或磁盘中可用的旧版本应用程序。
请注意 www.app.com/en/*
或 www.app.com/fr/*
运行良好
此时我不知道问题是我们的重写规则还是我们的js脚本重定向。
这是 /en 的 angular 构建脚本 -> ng build --output-path=dist/en --prod --base-href /en/ --i18n-locale en-CA --i18n-format=xlf
这是我们的根 index.html 代码:
<html>
<head>
<meta http-equiv="Cache-Control" content="no-cache, no-store, must-revalidate" />
<meta http-equiv="Pragma" content="no-cache" />
<meta http-equiv="Expires" content="0" />
<script>
var edRedirectManager = (function () {
var _this = {};
_this.storageLocaleKey = "EDLocale";
_this.locale = "";
_this.init = function(){
_this.locale = (_this.getUserLanguage());
}
_this.redirect = function () {
var currentUrl = new URL(window.location.href);
var lgPrefix = _this.getUrlPrefixByLanguage();
currentUrl.pathname = _this.insert(currentUrl.pathname,lgPrefix,0);
window.location.href = currentUrl.href;
}
_this.getUserLanguage = function () {
try {
_this.locale = localStorage.getItem(storageLocaleKey);
} catch (error) {}
if (!this.locale) {
if (navigator.language.toUpperCase().indexOf("FR") !== -1)
this.locale = "fr-CA";
else
this.locale = "en-CA";
localStorage.setItem(this.storageLocaleKey, this.locale);
}
return _this.locale;
}
_this.getUrlPrefixByLanguage = function(){
var lgPrefix = "/fr";
if(this.locale.indexOf('en') !== -1){
lgPrefix = "/en";
}
return lgPrefix;
}
_this.insert = function (main_string, ins_string, pos) {
if (typeof (pos) == "undefined") {
pos = 0;
}
if (typeof (ins_string) == "undefined") {
ins_string = '';
}
return main_string.slice(0, pos) + ins_string + main_string.slice(pos);
}
return _this;
})();
</script>
</head>
<body>
<script>
// self executing function here
edRedirectManager.init();
edRedirectManager.redirect();
</script>
</body>
</html>
出于某种原因 "/en/index.html" and/or "/fr/index.html" 页面在从根 "/" 触发时被缓存,这导致旧应用程序 main.js 加载
重定向工作正常...
我在 web.config 中使用 no-cache 值添加了这些设置标签 <location>
,现在这个问题消失了!
<configuration>
<location path="en/index.html">
<system.webServer>
<httpProtocol>
<customHeaders>
<add name="Cache-Control" value="no-cache" />
</customHeaders>
</httpProtocol>
</system.webServer>
</location>
<location path="fr/index.html">
<system.webServer>
<httpProtocol>
<customHeaders>
<add name="Cache-Control" value="no-cache" />
</customHeaders>
</httpProtocol>
</system.webServer>
</location>
<location path="index.html">
<system.webServer>
<httpProtocol>
<customHeaders>
<add name="Cache-Control" value="no-cache" />
</customHeaders>
</httpProtocol>
</system.webServer>
</location>
<system.webServer>
<urlCompression doDynamicCompression="true" />
<staticContent>
<mimeMap fileExtension=".json" mimeType="application/json" />
</staticContent>
<rewrite>
<rules>
<rule name="Angular Routes fr" stopProcessing="true">
<match url="fr/.*" />
<conditions logicalGrouping="MatchAll">
<add input="{REQUEST_FILENAME}" matchType="IsFile" negate="true" />
<add input="{REQUEST_FILENAME}" matchType="IsDirectory" negate="true" />
</conditions>
<action type="Rewrite" url="fr/index.html" />
</rule>
<rule name="Angular Routes en" stopProcessing="true">
<match url="en/.*" />
<conditions logicalGrouping="MatchAll">
<add input="{REQUEST_FILENAME}" matchType="IsFile" negate="true" />
<add input="{REQUEST_FILENAME}" matchType="IsDirectory" negate="true" />
</conditions>
<action type="Rewrite" url="en/index.html" />
</rule>
<rule name="Angular Routes default" stopProcessing="true">
<match url=".*" />
<conditions logicalGrouping="MatchAll">
<add input="{REQUEST_FILENAME}" matchType="IsFile" negate="true" />
<add input="{REQUEST_FILENAME}" matchType="IsDirectory" negate="true" />
</conditions>
<action type="Rewrite" url="/index.html" />
</rule>
</rules>
</rewrite>
</system.webServer>
</configuration>
我们目前在 Azure/App 服务上有 2 个版本的 Angular 应用程序来支持内部化。
托管在同一个地方但在不同的文件夹 /en 和 /fr。 我们的文件夹树看起来像这样
->
wwwroot/index.html
wwwroot/web.config
wwwroot/en/index.html
wwwroot/en/..
wwwroot/fr/index.html
wwwroot/fr/..
我们确实有一个 web.config 完美运行的重写规则。见下文:
<configuration>
<system.webServer>
<rewrite>
<rules>
<rule name="Angular Routes fr" stopProcessing="true">
<match url="fr/.*" />
<conditions logicalGrouping="MatchAll">
<add input="{REQUEST_FILENAME}" matchType="IsFile" negate="true" />
<add input="{REQUEST_FILENAME}" matchType="IsDirectory" negate="true" />
</conditions>
<action type="Rewrite" url="fr/" />
</rule>
<rule name="Angular Routes en" stopProcessing="true">
<match url="en/.*" />
<conditions logicalGrouping="MatchAll">
<add input="{REQUEST_FILENAME}" matchType="IsFile" negate="true" />
<add input="{REQUEST_FILENAME}" matchType="IsDirectory" negate="true" />
</conditions>
<action type="Rewrite" url="en/" />
</rule>
</rules>
</rewrite>
</system.webServer>
</configuration>
这是一个转折点;我们确实提供了根 index.html,以防用户导航到 www.app.com/*
而不是 www.app.com/en
。
在这种情况下,root index.html 被触发,我们 运行 一些 js 脚本根据本地存储语言使用 "window.location.href" 用户重定向。
出于某种原因,当我们从根 www.app.com
查询 url 时
浏览器 link 并将第一个版本缓存到此 url.
如果我们使用这样的资源查询 url www.app.com/en/*
浏览器 link 尽管域相同,但此路径的另一个版本。
问题是每次我们部署新版本时,只有任何资源的路径会被更新,例如:www.app.com/en/*
或 www.app.com/fr/*
但根 url www.app.com
坚持使用旧版本,永不更新。
如果用户使用 root url,它将被重定向到仅在内存或磁盘中可用的旧版本应用程序。
请注意 www.app.com/en/*
或 www.app.com/fr/*
运行良好
此时我不知道问题是我们的重写规则还是我们的js脚本重定向。
这是 /en 的 angular 构建脚本 -> ng build --output-path=dist/en --prod --base-href /en/ --i18n-locale en-CA --i18n-format=xlf
这是我们的根 index.html 代码:
<html>
<head>
<meta http-equiv="Cache-Control" content="no-cache, no-store, must-revalidate" />
<meta http-equiv="Pragma" content="no-cache" />
<meta http-equiv="Expires" content="0" />
<script>
var edRedirectManager = (function () {
var _this = {};
_this.storageLocaleKey = "EDLocale";
_this.locale = "";
_this.init = function(){
_this.locale = (_this.getUserLanguage());
}
_this.redirect = function () {
var currentUrl = new URL(window.location.href);
var lgPrefix = _this.getUrlPrefixByLanguage();
currentUrl.pathname = _this.insert(currentUrl.pathname,lgPrefix,0);
window.location.href = currentUrl.href;
}
_this.getUserLanguage = function () {
try {
_this.locale = localStorage.getItem(storageLocaleKey);
} catch (error) {}
if (!this.locale) {
if (navigator.language.toUpperCase().indexOf("FR") !== -1)
this.locale = "fr-CA";
else
this.locale = "en-CA";
localStorage.setItem(this.storageLocaleKey, this.locale);
}
return _this.locale;
}
_this.getUrlPrefixByLanguage = function(){
var lgPrefix = "/fr";
if(this.locale.indexOf('en') !== -1){
lgPrefix = "/en";
}
return lgPrefix;
}
_this.insert = function (main_string, ins_string, pos) {
if (typeof (pos) == "undefined") {
pos = 0;
}
if (typeof (ins_string) == "undefined") {
ins_string = '';
}
return main_string.slice(0, pos) + ins_string + main_string.slice(pos);
}
return _this;
})();
</script>
</head>
<body>
<script>
// self executing function here
edRedirectManager.init();
edRedirectManager.redirect();
</script>
</body>
</html>
出于某种原因 "/en/index.html" and/or "/fr/index.html" 页面在从根 "/" 触发时被缓存,这导致旧应用程序 main.js 加载
重定向工作正常...
我在 web.config 中使用 no-cache 值添加了这些设置标签 <location>
,现在这个问题消失了!
<configuration>
<location path="en/index.html">
<system.webServer>
<httpProtocol>
<customHeaders>
<add name="Cache-Control" value="no-cache" />
</customHeaders>
</httpProtocol>
</system.webServer>
</location>
<location path="fr/index.html">
<system.webServer>
<httpProtocol>
<customHeaders>
<add name="Cache-Control" value="no-cache" />
</customHeaders>
</httpProtocol>
</system.webServer>
</location>
<location path="index.html">
<system.webServer>
<httpProtocol>
<customHeaders>
<add name="Cache-Control" value="no-cache" />
</customHeaders>
</httpProtocol>
</system.webServer>
</location>
<system.webServer>
<urlCompression doDynamicCompression="true" />
<staticContent>
<mimeMap fileExtension=".json" mimeType="application/json" />
</staticContent>
<rewrite>
<rules>
<rule name="Angular Routes fr" stopProcessing="true">
<match url="fr/.*" />
<conditions logicalGrouping="MatchAll">
<add input="{REQUEST_FILENAME}" matchType="IsFile" negate="true" />
<add input="{REQUEST_FILENAME}" matchType="IsDirectory" negate="true" />
</conditions>
<action type="Rewrite" url="fr/index.html" />
</rule>
<rule name="Angular Routes en" stopProcessing="true">
<match url="en/.*" />
<conditions logicalGrouping="MatchAll">
<add input="{REQUEST_FILENAME}" matchType="IsFile" negate="true" />
<add input="{REQUEST_FILENAME}" matchType="IsDirectory" negate="true" />
</conditions>
<action type="Rewrite" url="en/index.html" />
</rule>
<rule name="Angular Routes default" stopProcessing="true">
<match url=".*" />
<conditions logicalGrouping="MatchAll">
<add input="{REQUEST_FILENAME}" matchType="IsFile" negate="true" />
<add input="{REQUEST_FILENAME}" matchType="IsDirectory" negate="true" />
</conditions>
<action type="Rewrite" url="/index.html" />
</rule>
</rules>
</rewrite>
</system.webServer>
</configuration>