Браузер сохраняет запутанную кэшированную версию приложения angular в корневом каталоге index.html размещенную с помощью службы приложений Azure

#angular #azure #iis #web-config #angular-i18n

#angular #azure #iis #web-config #angular-i18n

Вопрос:

В настоящее время у нас есть 2 версии нашего приложения Angular в Azure / App services для поддержки интернализации.

Они размещены в одном и том же месте, но в разных папках / 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>
  

Вот в чем изюминка; мы предоставляем root index.html в случае, если пользователь переходит к www.app.com/* вместо www.app.com/en .
В этом случае корневой index.html запускается, и мы запускаем некоторый js-скрипт для перенаправления с использованием «window.location.href» пользователь в зависимости от языка локального хранилища.

По какой-то причине, когда мы запрашиваем URL-адрес из root www.app.com , браузер ссылается и кэширует первую версию по этому URL.

Если мы запрашиваем URL-адрес с помощью ресурса, подобного этому www.app.com/en/* , браузер ссылается на ДРУГУЮ версию по этому пути, несмотря на тот же домен.

Проблема в том, что каждый раз, когда мы развертываем новую версию, обновляется только путь с любыми ресурсами, например: www.app.com/en/* или www.app.com/fr/* , но корневой URL www.app.com остается привязанным к старой версии и никогда не обновляется.

Если пользователь использует корневой URL, он будет перенаправлен на старую версию приложения, доступную только в памяти или на диске.

Обратите внимание, что www.app.com/en/* or www.app.com/fr/* работает отлично

На данный момент я не знаю, является ли проблема нашими правилами перезаписи или перенаправлением нашего js-скрипта.

Вот сценарий сборки angular для / ru -> 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>
  

Комментарии:

1. не могли бы вы, пожалуйста, приложить точные запросы и ответы для index.html и / en или / fr выполняются при переходе к индексации? это легко можно сделать с помощью флажка «Сохранить журнал» на вкладке chrome devtools network

2. по умолчанию на вкладке сеть установлен флажок «отключить кэш». это может быть причиной, по которой это работало в прошлый раз

3. У меня та же проблема, но без элементов интернационализации. Браузер загружается из кэша при выполнении запроса к корневому каталогу (код ответа 200?), Но по любому другому пути возвращает либо 200 (получает новую версию), либо 304 без изменений (правильная кэшированная версия). У меня такое чувство, что это может быть проблемой Azure…

Ответ №1:

По какой-то причине «/en/index.html « и / или «/fr/index.html « страница была кэширована при запуске из root » / » что приводит к устареванию приложения main.js для загрузки

Перенаправление сработало, просто оштрафован…

Я добавил тег настройки тезисов <location> в web.config со значением no-cache, и теперь эта проблема устранена!

 <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>