Размещение и развертывание ASP.NET Core Blazor WebAssembly

Примечание.

Это не последняя версия этой статьи. Сведения о текущем выпуске см. в ASP.NET версии Core 8.0 этой статьи.

В этой статье вы узнаете, как размещать и развертывать приложение Blazor WebAssembly с помощью ASP.NET Core, сетей доставки содержимого (CDN), файловых серверов и GitHub Pages.

При использовании модели размещения Blazor WebAssembly:

  • Приложение Blazor, его зависимости и среда выполнения .NET скачиваются в браузере параллельно.
  • Приложение выполняется непосредственно в потоке пользовательского интерфейса браузера.

Эта статья относится к сценарию развертывания, в котором Blazor приложение размещается на статическом веб-сервере или службе размещения, .NET не используется для обслуживания Blazor приложения. Эта стратегия рассматривается в разделе Автономное развертывание, где приводятся сведения о размещении приложения Blazor WebAssembly в качестве дочернего приложения IIS.

Поддерживаются следующие стратегии развертывания:

Формат упаковки webcil для сборок .NET

Webcil — это удобный для интернета формат упаковки сборок .NET, предназначенный для использования Blazor WebAssembly в ограничивающих сетевых средах. Файлы Webcil используют стандартную оболочку WebAssembly, где сборки развертываются как файлы WebAssembly, использующие стандартное .wasm расширение файла.

Webcil — это формат упаковки по умолчанию при публикации Blazor WebAssembly приложения. Чтобы отключить использование Webcil, задайте в файле проекта приложения следующее свойство MS Build:

<PropertyGroup>
  <WasmEnableWebcil>false</WasmEnableWebcil>
</PropertyGroup>

Компиляция AOT

Blazor WebAssembly поддерживает упреждающую компиляцию (AOT), с помощью которой вы можете скомпилировать код .NET непосредственно в WebAssembly. Компиляция AOT позволяет повысить производительность среды выполнения за счет увеличения размера приложения.

Без включения компиляции Blazor WebAssembly AOT приложения выполняются в браузере с помощью интерпретатора промежуточного языка .NET (IL ), реализованного в WebAssembly с частичной поддержкой JIT-среды выполнения, неофициально называемой Jiterpreter. Так как код .NET IL интерпретируется, приложения обычно выполняются медленнее, чем они будут выполняться на стороне сервера среды выполнения JIT на стороне сервера без какой-либо интерпретации IL. Компиляция AOT позволяет решить эту проблему с производительностью, выполняя компиляцию кода .NET приложения непосредственно в WebAssembly для выполнения собственной сборки через браузер. Повышение производительности AOT может привести к значительному улучшению приложений, выполняющих ресурсоемкие задачи. Недостаток использования компиляции AOT заключается в том, что приложения, скомпилированные с помощью AOT, обычно больше их аналогов, интерпретируемых с помощью IL, поэтому загрузка клиента при первом запросе обычно занимает больше времени.

Без включения компиляции Blazor WebAssembly AOT приложения выполняются в браузере с помощью интерпретатора промежуточного языка .NET (IL), реализованного в WebAssembly. Поскольку код .NET интерпретируется, приложения обычно выполняются медленнее, чем на стороне сервера среды выполнения JIT .NET. Компиляция AOT позволяет решить эту проблему с производительностью, выполняя компиляцию кода .NET приложения непосредственно в WebAssembly для выполнения собственной сборки через браузер. Повышение производительности AOT может привести к значительному улучшению приложений, выполняющих ресурсоемкие задачи. Недостаток использования компиляции AOT заключается в том, что приложения, скомпилированные с помощью AOT, обычно больше их аналогов, интерпретируемых с помощью IL, поэтому загрузка клиента при первом запросе обычно занимает больше времени.

Рекомендации по установке средств сборки .NET WebAssembly см. в разделе Инструментарий для ASP.NET Core Blazor.

Чтобы включить компиляцию AOT WebAssembly, добавьте свойство <RunAOTCompilation>, которому присвоено значение true, в файл проекта приложения Blazor WebAssembly:

<PropertyGroup>
  <RunAOTCompilation>true</RunAOTCompilation>
</PropertyGroup>

Чтобы скомпилировать приложение в WebAssembly, опубликуйте приложение. Публикация конфигурации Release гарантирует, что для уменьшения размера опубликованного приложения также выполняется компоновка на промежуточном языке .NET.

dotnet publish -c Release

Компиляция AOT WebAssembly выполняется только при публикации проекта. Компиляция AOT не используется, когда проект запускается во время разработки (среда Development), поскольку компиляция AOT небольших проектов обычно занимает несколько минут и может значительно увеличиться для больших проектов. Сокращение времени сборки для компиляции AOT планируется в будущих выпусках ASP.NET Core.

Размер приложения Blazor WebAssembly, скомпилированного в режиме AOT, обычно превышает размер приложения, скомпилированного в IL .NET.

  • Несмотря на то, что разница в размере зависит от приложения, большинство приложений, скомпилированных в режиме AOT, вдвое больше их версий, скомпилированных с помощью IL. Это означает, что при использовании компиляции AOT время загрузки больше, но скорость выполнения выше. Применение такого компромисса в отношении компиляции AOT зависит от приложения. Обычно преимущества компиляции AOT ощутимы для приложений Blazor WebAssembly, которые потребляют много ресурсов ЦП.

  • Больший размер приложения, скомпилированного в режиме AOT, обусловлен двумя условиями:

    • Требуется больше кода для представления высокоуровневых инструкций IL .NET в собственном формате WebAssembly.
    • AOT не усекает управляемые библиотеки DLL при публикации приложения. Blazor требует библиотек DLL для метаданных отражения и для поддержки некоторых функций среды выполнения .NET. Требование использовать библиотеки DLL в клиенте увеличивает размер скачиваемых ресурсов, но обеспечивает более совместимый интерфейс .NET.

Примечание.

Сведения о свойствах и целевых объектах MSBuild Mono/WebAssembly см. в разделе WasmApp.Common.targets (dotnet/runtimeрепозиторий GitHub). Официальная документация по общим свойствам MSBuild планируется для параметров конфигурации msbuild Document blazor (dotnet/docs #27395).

Обрезать .NET IL после предварительной компиляции (AOT)

Параметр WasmStripILAfterAOT MSBuild позволяет удалить промежуточный язык .NET (IL) для скомпилированных методов после выполнения компиляции AOT в WebAssembly, что снижает размер _framework папки.

В файле проекта приложения сделайте следующее:

<PropertyGroup>
  <RunAOTCompilation>true</RunAOTCompilation>
  <WasmStripILAfterAOT>true</WasmStripILAfterAOT>
</PropertyGroup>

Этот параметр обрезает код IL для большинства скомпилированных методов, включая методы из библиотек и методов в приложении. Не все скомпилированные методы можно обрезать, так как некоторые из них по-прежнему требуются интерпретатором .NET во время выполнения.

Чтобы сообщить о проблеме с параметром обрезки, откройте проблему в dotnet/runtime репозитории GitHub.

Отключите свойство обрезки, если оно не позволяет приложению работать нормально:

<WasmStripILAfterAOT>false</WasmStripILAfterAOT>

Повторная компоновка среды выполнения

Одна из самых крупных частей приложения Blazor WebAssembly — это среда выполнения .NET на основе WebAssembly (dotnet.wasm), которую браузер должен загрузить при первом обращении к приложению через браузер пользователя. Повторная компоновка среды выполнения .NET WebAssembly обрезает неиспользуемый код среды выполнения и тем самым повышает скорость загрузки.

Повторная компоновка среды выполнения требует установки средств сборки .NET WebAssembly. Дополнительные сведения см. в статье Инструментарий для ASP.NET Core Blazor.

При наличии установленных средств сборки .NET WebAssembly повторная компоновка среды выполнения выполняется автоматически, когда приложение публикуется в конфигурации Release. Уменьшение размера особенно существенно при отключении глобализации. Дополнительные сведения см. в статье Глобализация и локализация в ASP.NET Core Blazor.

Внимание

При повторном связывании среды выполнения методы JavaScript, вызываемые JavaScript, выполняются повторно, если они не защищены. Дополнительные сведения см. в статье Вызов методов .NET из функций JavaScript в ASP.NET Core Blazor.

Настройка способа загрузки загрузочных ресурсов

Настройте способ загрузки загрузочных ресурсов с помощью API loadBootResource. Дополнительные сведения см. в статье Запуск ASP.NET Core Blazor.

Сжатие

При публикации приложения Blazor WebAssembly выходные данные статически сжимаются, чтобы уменьшить размер приложения и исключить издержки на сжатие среды выполнения. Используются следующие алгоритмы сжатия:

Blazor использует узел для обслуживания соответствующих сжатых файлов. При размещении автономного приложения Blazor WebAssembly, возможно, потребуется реализовать дополнительные действия для обслуживания статически сжатых файлов.

Blazor использует узел для обслуживания соответствующих сжатых файлов. При использовании проекта ASP.NET Core HostedBlazor WebAssembly основной проект может выполнять согласование содержимого и обслуживать статически сжатые файлы. При размещении автономного приложения Blazor WebAssembly, возможно, потребуется реализовать дополнительные действия для обслуживания статически сжатых файлов.

  • Сведения о конфигурации сжатия IIS web.config см. в разделе IIS: сжатие Brotli и Gzip.
  • При размещении в статических решениях размещения, которые не поддерживают согласование содержимого с статически сжатым файлом, рассмотрите возможность настройки приложения для получения и декодирования сжатых файлов Brotli:

Получите декодатор JavaScript Brotli из google/brotli репозитория GitHub. Сокращенный файл декодера называется decode.min.js и находится в папке js репозитория.

Примечание.

Если сокращенная версия скрипта decode.js (decode.min.js) не работает, попробуйте вместо нее использовать не сокращенную версию (decode.js).

обновите приложение для использования декодера.

В файле wwwroot/index.html установите для autostart значение false в теге Blazor<script>:

<script src="_framework/blazor.webassembly.js" autostart="false"></script>

После Blazorтега <script> и перед закрывающим </body> тегом добавьте следующий блок кода <script> JavaScript.

Blazor Веб-приложение:

<script type="module">
  import { BrotliDecode } from './decode.min.js';
  Blazor.start({
    webAssembly: {
      loadBootResource: function (type, name, defaultUri, integrity) {
        if (type !== 'dotnetjs' && location.hostname !== 'localhost' && type !== 'configuration' && type !== 'manifest') {
          return (async function () {
            const response = await fetch(defaultUri + '.br', { cache: 'no-cache' });
            if (!response.ok) {
              throw new Error(response.statusText);
            }
            const originalResponseBuffer = await response.arrayBuffer();
            const originalResponseArray = new Int8Array(originalResponseBuffer);
            const decompressedResponseArray = BrotliDecode(originalResponseArray);
            const contentType = type === 
              'dotnetwasm' ? 'application/wasm' : 'application/octet-stream';
            return new Response(decompressedResponseArray, 
              { headers: { 'content-type': contentType } });
          })();
        }
      }
    }
  });
</script>

Изолированное решение Blazor WebAssembly:

<script type="module">
  import { BrotliDecode } from './decode.min.js';
  Blazor.start({
    loadBootResource: function (type, name, defaultUri, integrity) {
      if (type !== 'dotnetjs' && location.hostname !== 'localhost' && type !== 'configuration') {
        return (async function () {
          const response = await fetch(defaultUri + '.br', { cache: 'no-cache' });
          if (!response.ok) {
            throw new Error(response.statusText);
          }
          const originalResponseBuffer = await response.arrayBuffer();
          const originalResponseArray = new Int8Array(originalResponseBuffer);
          const decompressedResponseArray = BrotliDecode(originalResponseArray);
          const contentType = type === 
            'dotnetwasm' ? 'application/wasm' : 'application/octet-stream';
          return new Response(decompressedResponseArray, 
            { headers: { 'content-type': contentType } });
        })();
      }
    }
  });
</script>

Дополнительные сведения о загрузке загрузочных ресурсов см. в статье Запуск ASP.NET Core Blazor.

Чтобы отключить сжатие, добавьте свойство CompressionEnabled MSBuild в файл проекта приложения и задайте для него значение false.

<PropertyGroup>
  <CompressionEnabled>false</CompressionEnabled>
</PropertyGroup>

Свойство CompressionEnabled можно передать в команду dotnet publish с помощью следующего синтаксиса в командной оболочке.

dotnet publish -p:CompressionEnabled=false

Чтобы отключить сжатие, добавьте свойство BlazorEnableCompression MSBuild в файл проекта приложения и задайте для него значение false.

<PropertyGroup>
  <BlazorEnableCompression>false</BlazorEnableCompression>
</PropertyGroup>

Свойство BlazorEnableCompression можно передать в команду dotnet publish с помощью следующего синтаксиса в командной оболочке.

dotnet publish -p:BlazorEnableCompression=false

Переопределение URL-адресов для маршрутизации

Запросы маршрутизации для компонентов страниц в Blazor WebAssembly приложении не так просто, как запросы маршрутизации в Blazor Server приложении. Рассмотрим сценарий с приложением Blazor WebAssembly с двумя компонентами:

  • Main.razor: загружается в корне приложения и содержит ссылку на About компонент (href="About").
  • About.razor: компонент About.

При запросе документа приложения по умолчанию в адресной строке браузера (например, https://www.contoso.com/):

  1. Браузер отправляет запрос.
  2. Возвращается страница по умолчанию; обычно это index.html.
  3. Страница index.html обеспечивает начальную загрузку приложения.
  4. Router загрузка компонентов и RazorMain отрисовка компонента.

На странице Main возможность выбора ссылки на компонент About доступна на клиентском компьютере, так как маршрутизатор Blazor не разрешает браузеру сделать запрос в Интернете к www.contoso.com для About и сам обрабатывает отображенный компонент About. Все запросы внутренних конечных точек в Blazor WebAssembly приложении работают так же: запросы не активируют запросы на основе браузера к размещенным на сервере ресурсам в Интернете. Маршрутизатор обрабатывает запросы внутренним образом.

Если запрос www.contoso.com/About сделан с помощью адресной строки браузера, он завершится ошибкой. Такой ресурс не существует на интернет-узле приложения, поэтому возвращается ответ 404 — Not Found (не найдено).

Так как браузеры выполняют запросы к интернет-узлам для страниц на стороне клиента, веб-серверам и службам размещения необходимо переопределять все запросы к ресурсам, физически находящимся не на сервере, в случае страницы index.html. Когда index.html возвращается, маршрутизатор Blazor приложения берет на себя управление и отвечает необходимым ресурсом.

При развертывании на сервере IIS можно использовать модуль переопределения URL-адресов с опубликованным файлом web.config приложения. Дополнительные сведения см. в описании IIS.

Размещенное развертывание с использованием ASP.NET Core

Размещенное развертывание обслуживает приложение Blazor WebAssembly для браузеров из приложения ASP.NET Core, выполняющегося на веб-сервере.

Клиентское приложение Blazor WebAssembly будет опубликовано в папку /bin/Release/{TARGET FRAMEWORK}/publish/wwwroot серверного приложения вместе со статическими веб-ресурсами серверного приложения. Оба приложения развертываются вместе. Веб-сервер, позволяющий размещать приложения ASP.NET Core, является обязательным. Для размещаемого развертывания Visual Studio включает шаблон проекта Приложение Blazor WebAssembly (шаблон blazorwasm при использовании команды dotnet new) с выбранным параметром Hosted (-ho|--hosted при использовании команды dotnet new).

Дополнительные сведения см. в следующих статьях:

Размещенное развертывание исполняемого файла, зависящего от среды выполнения для определенной платформы

Чтобы развернуть размещенное приложение Blazor WebAssembly в качестве исполняемого файла, зависящего от среды выполнения для определенной платформы (не автономной), используйте следующие рекомендации на основе используемых инструментов.

Visual Studio

По умолчанию для созданного профиля публикации (.pubxml) настраивается автономное развертывание. Убедитесь, что профиль публикации проекта Server содержит свойство MSBuild <SelfContained>, которому присвоено значение false.

В файле профиля публикации .pubxml в папке Properties проекта Server выполните следующие действия:

<SelfContained>false</SelfContained>

Задайте Идентификатор среды выполнения (RID) с помощью параметра Целевая среда выполнения в области Параметры пользовательского интерфейса Публикация, который создает свойство MSBuild <RuntimeIdentifier> в профиле публикации:

<RuntimeIdentifier>{RID}</RuntimeIdentifier>

В предыдущей конфигурации заполнитель {RID} представляет собой Идентификатор среды выполнения (RID).

Опубликуйте проект Server в конфигурации Выпуск.

Примечание.

Вы можете опубликовать приложение с параметрами профиля публикации с помощью CLI .NET, передав /p:PublishProfile={PROFILE} в команду dotnet publish, где заполнитель {PROFILE} представляет собой профиль. Дополнительные сведения см. в разделах Профили публикации и Пример публикации папки в статье Профили публикации Visual Studio (.pubxml) для развертывания приложения ASP.NET Core. Если вы передаете RID в команде dotnet publish, а не в профиле публикации, используйте свойство MSBuild (/p:RuntimeIdentifier) с командой, а не с параметром -r|--runtime.

Интерфейс командной строки.NET

Настройте автономное развертывание, поместив свойство MSBuild <SelfContained>, имеющее значение false, в раздел <PropertyGroup> в файле проекта Server:

<SelfContained>false</SelfContained>

Внимание

Свойство SelfContained должно быть помещено в файл проекта Server. Свойство не может быть задано с помощью команды dotnet publish и параметра --no-self-contained или свойства MSBuild /p:SelfContained=false.

Задайте Идентификатор среды выполнения (RID), используя любой из указанных ниже подходов:

  • Вариант 1. Задайте RID в разделе <PropertyGroup> в файле проекта Server:

    <RuntimeIdentifier>{RID}</RuntimeIdentifier>
    

    В предыдущей конфигурации заполнитель {RID} представляет собой Идентификатор среды выполнения (RID).

    Опубликуйте приложение в конфигурации выпуска из проекта Server:

    dotnet publish -c Release
    
  • Вариант 2. Передайте RID в команде dotnet publish в качестве свойства MSBuild (/p:RuntimeIdentifier), а не с параметром -r|--runtime:

    dotnet publish -c Release /p:RuntimeIdentifier={RID}
    

    В предыдущей команде заполнитель {RID} представляет собой Идентификатор среды выполнения (RID).

Дополнительные сведения см. в следующих статьях:

Размещенное развертывание с несколькими приложениями Blazor WebAssembly

Дополнительные сведения см. в статье Несколько размещенных приложений Blazor WebAssembly ASP.NET Core.

Автономное развертывание

Автономное развертывание обрабатывает приложение Blazor WebAssembly как набор статических файлов, которые будут запрашиваться непосредственно клиентами. Любой статический файловый сервер способен обслуживать приложение Blazor.

Ресурсы автономного развертывания публикуются в папке /bin/Release/{TARGET FRAMEWORK}/publish/wwwroot.

Служба приложений Azure

Приложения Blazor WebAssembly можно развернуть в службах приложений Azure в Windows. При этом приложение размещается в службах IIS.

Развертывание автономного приложения Blazor WebAssembly в Службе приложений Azure для Linux в настоящее время не поддерживается. Рекомендуем разместить автономное приложение Blazor WebAssembly с помощью службы Статические веб-приложения Azure, которая поддерживает этот сценарий.

Служба статических веб-приложений Azure

Разверните приложение для Blazor WebAssembly Статические веб-приложения Azure с помощью одного из следующих подходов:

Развертывание из Visual Studio

Чтобы развернуть из Visual Studio, создайте профиль публикации для Статические веб-приложения Azure:

  1. Сохраните все несохраненные работы в проекте, так как в процессе может потребоваться перезапуск Visual Studio.

  2. В пользовательском интерфейсе публикации Visual Studio выберите "Целевой>целевой объект> Azure>"Статические веб-приложения Azure чтобы создать профиль публикации.

  3. Если компонент средств веб-заданий Azure для Visual Studio не установлен, появится запрос на установку компонента ASP.NET и веб-разработки. Следуйте инструкциям по установке средств с помощью установщика Visual Studio. Visual Studio закрывает и открывается автоматически при установке средств. После установки средств начните с первого шага, чтобы создать профиль публикации.

  4. В конфигурации профиля публикации укажите имя подписки. Выберите существующий экземпляр или нажмите кнопку "Создать новый экземпляр". При создании нового экземпляра в пользовательском интерфейсе статического веб-приложения портал Azure задайте для источника сведений>о развертывании значение Other. Дождитесь завершения развертывания в портал Azure, прежде чем продолжить.

  5. В конфигурации профиля публикации выберите экземпляр Статические веб-приложения Azure из группы ресурсов экземпляра. Нажмите кнопку "Готово ", чтобы создать профиль публикации. Если Visual Studio запрашивает установку интерфейса командной строки Статические веб-приложения (SWA), установите интерфейс командной строки, следуя инструкциям. Для интерфейса командной строки SWA требуется NPM/Node.js (документация по Visual Studio).

После создания профиля публикации разверните приложение в Статические веб-приложения Azure экземпляре с помощью профиля публикации, нажав кнопку "Опубликовать".

Развертывание из GitHub

Сведения о развертывании из репозитория GitHub см. в руководстве по созданию статического веб-приложения с Blazor помощью Статические веб-приложения Azure.

IIS

IIS можно использовать как полнофункциональный статический файловый сервер для приложений Blazor. Чтобы настроить IIS для размещения Blazor, перейдите к разделу Развертывание статического веб-сайта на IIS.

Опубликованные ресурсы создаются в /bin/Release/{TARGET FRAMEWORK}/publish папке или bin\Release\{TARGET FRAMEWORK}\browser-wasm\publish в зависимости от того, какая версия пакета SDK используется и где {TARGET FRAMEWORK} заполнитель является целевой платформой. Разместите содержимое папки publish на веб-сервере или в службе размещения.

web.config.

При публикации проекта Blazor создается файл web.config со следующей конфигурацией IIS:

  • типы MIME
  • Сжатие HTTP включено для следующих типов MIME:
    • application/octet-stream
    • application/wasm
  • Устанавливаются правила переопределения URL-адресов:
    • Предоставление подкаталога для размещения статических ресурсов приложения (wwwroot/{PATH REQUESTED}).
    • Создание резервной маршрутизации для одностраничного приложения, которая позволяет перенаправлять запросы, относящиеся к нефайловым ресурсам, к документу приложения по умолчанию в папке статических ресурсов (wwwroot/index.html).

Использование пользовательского web.config

Чтобы использовать пользовательский файл web.config:

  1. Поместите пользовательский файл web.config в корневую папку проекта.
  2. Опубликуйте проект. Дополнительные сведения см. в статье Размещение и развертывание ASP.NET Core Blazor.
  1. Поместите пользовательский файл web.config в корневую папку проекта. Для размещенного решенияBlazor WebAssembly поместите файл в папку проекта Server.
  2. Опубликуйте проект. Для размещенного решения Blazor WebAssembly опубликуйте решение из проекта Server. Дополнительные сведения см. в статье Размещение и развертывание ASP.NET Core Blazor.

Если создание или преобразование пакета SDK web.config во время публикации либо не перемещает файл в опубликованные ресурсы в publish папке, либо изменяет настраиваемую конфигурацию в пользовательском web.config файле, используйте любой из следующих подходов, при необходимости, чтобы получить полный контроль над процессом:

  • Если пакет SDK не создает файл, например в автономном приложении или в зависимости от того, какая версия пакета SDK используется и где {TARGET FRAMEWORK} заполнитель является целевой платформой, задайте <PublishIISAssets> для true свойства значение в файле проекта (.csproj).bin\Release\{TARGET FRAMEWORK}\browser-wasm\publish/bin/Release/{TARGET FRAMEWORK}/publish/wwwrootBlazor WebAssembly Обычно для автономных приложений WebAssembly это единственный обязательный параметр для перемещения пользовательского web.config файла и предотвращения преобразования файла пакетом SDK.

    <PropertyGroup>
      <PublishIISAssets>true</PublishIISAssets>
    </PropertyGroup>
    
  • Отключите преобразование пакета SDK web.config в файле проекта (.csproj):

    <PropertyGroup>
      <IsTransformWebConfigDisabled>true</IsTransformWebConfigDisabled>
    </PropertyGroup>
    
  • Добавьте пользовательский целевой объект в файл проекта (.csproj) для перемещения пользовательского web.config файла. В следующем примере пользовательский web.config файл помещается разработчиком в корне проекта. web.config Если файл находится в другом месте, укажите путь к файлу.SourceFiles В следующем примере указывается publish папка с $(PublishDir), но укажите путь к DestinationFolder пользовательскому расположению вывода.

    <Target Name="CopyWebConfig" AfterTargets="Publish">
      <Copy SourceFiles="web.config" DestinationFolder="$(PublishDir)" />
    </Target>
    

Установка модуля переопределения URL-адресов

Модуль переопределения URL-адресов нужен, чтобы переопределять URL-адреса. Модуль не устанавливается по умолчанию и недоступен для установки как компонент службы роли веб-сервера (IIS). Модуль необходимо скачать с веб-сайта IIS. Для его установки используйте установщик веб-платформы.

  1. Локально перейдите на страницу скачивания модуля переопределения URL-адресов. В англоязычной версии выберите WebPI для скачивания установщика веб-платформы. Для других языков выберите подходящую архитектуру сервера (x86 или x64) для скачивания установщика.
  2. Скопируйте установщик на сервер. Запустите установщик. Нажмите кнопку Установить и примите условия лицензионного соглашения. Перезагрузка сервера после завершения установки не требуется.

Настройка веб-сайта

Установите для веб сайта физический путь к папке приложения. Эта папка содержит следующее.

  • Файл web.config, который используется службами IIS для настройки веб-сайта, включая необходимые правила перенаправления и типы содержимого файлов.
  • Папку статических ресурсов приложения.

Размещение в качестве дочернего приложения IIS

Если автономное приложение размещено как дочернее приложение IIS, выполните одно из следующих действий:

  • Отключите наследуемый обработчик модуля ASP.NET Core.

    Удалите обработчик в опубликованном файле web.config приложения Blazor, добавив раздел <handlers> в раздел <system.webServer> в файл:

    <handlers>
      <remove name="aspNetCore" />
    </handlers>
    
  • Отключите наследование раздела <system.webServer> от корневого (родительского) приложения, используя <location> со значением false для inheritInChildApplications:

    <?xml version="1.0" encoding="utf-8"?>
    <configuration>
      <location path="." inheritInChildApplications="false">
        <system.webServer>
          <handlers>
            <add name="aspNetCore" ... />
          </handlers>
          <aspNetCore ... />
        </system.webServer>
      </location>
    </configuration>
    

    Примечание.

    Отключение наследования корневого (родительского) раздела <system.webServer> приложения является конфигурацией по умолчанию для опубликованных приложений с использованием пакета SDK для .NET.

Удаление обработчика или отключение наследования выполняется вместе с настройкой базового пути приложения. Задайте базовый путь приложения в файле index.html приложения как псевдоним IIS, используемый при настройке дочернего приложения в IIS.

Настройте базовый путь приложения, следуя инструкциям в статье "Узел" и разверните ASP.NET Core Blazor .

Алгоритмы сжатия Brotli и Gzip

Этот раздел относится только к автономным приложениям Blazor WebAssembly .

Этот раздел относится только к изолированным приложениям Blazor WebAssembly. Размещенные приложения Blazor используют файл web.config приложения ASP.NET Core по умолчанию, а не файл, привязанный в рамках этого раздела.

С помощью файла web.config можно настроить IIS для обслуживания ресурсов Blazor, сжатых с помощью алгоритма Brotli или Gzip, для изолированных приложений Blazor WebAssembly. Пример файла конфигурации см. по адресу web.config.

В следующих сценариях, возможно, потребуется дополнительно настроить пример файла web.config:

  • Спецификация приложения вызывает любой из следующих вариантов:
    • обслуживание сжатых файлов, которые не настраиваются в примере файла web.config;
    • обслуживание сжатых файлов, настроенных в примере файла web.config в несжатом формате.
  • Конфигурация IIS сервера (например, applicationHost.config) предоставляет значения IIS по умолчанию на уровне сервера. Требуемая для приложения конфигурация IIS может отличаться от представленной в примере файла web.config. Это зависит от конфигурации на уровне сервера.

Дополнительные сведения о пользовательских web.config файлах см. в разделе "Использование пользовательского web.config ".

Устранение неполадок

Если получено сообщение 500 — Internal Server Error (внутренняя ошибка сервера), а диспетчер служб IIS возвращает ошибки при попытке получить доступ к конфигурации веб сайта, убедитесь, что установлен модуль переопределения URL-адресов. Если модуль не установлен, IIS не может проанализировать файл web.config. Это предотвращает загрузку конфигурации веб сайта диспетчером служб IIS и передачу статических файлов Blazor c веб-сайта.

Дополнительные сведения об устранении неполадок развертывания в службах IIS см. в разделе Устранение неполадок ASP.NET Core в Службе приложений Azure и IIS.

Хранилище Azure

Размещение статических файлов службы хранилища Azure предусматривает размещение бессерверного приложения Blazor. Поддерживаются пользовательские доменные имена, сеть доставки содержимого Azure (CDN) и HTTPS.

Если служба BLOB-объектов настроена для размещения статических веб-сайтов в учетной записи хранения:

  • Задайте для параметра Имя документа индекса значение index.html.
  • Задайте для параметра Путь к документу с ошибкой значение index.html. Компоненты Razor и другие конечные точки, не являющиеся файлами, не имеют физических путей в статическом содержимом, хранящемся в службе BLOB-объектов. При получении запроса для одного из этих ресурсов, который должен обрабатываться маршрутизатором Blazor, ошибка 404 - Объект не найден, создаваемая службой BLOB-объектов, перенаправляет запрос, используя путь к документу с ошибкой. При этом возвращается большой двоичный объект index.html, и маршрутизатор Blazor загружает и обрабатывает путь.

Если файлы не загружаются во время выполнения из-за недопустимых типов MIME в заголовках файлов Content-Type, выполните одно из следующих действий:

  • Настройте средства для установки правильных типов MIME (заголовков Content-Type) при развертывании файлов.

  • Измените типы MIME (заголовки Content-Type) для файлов после развертывания приложения.

    В Обозревателе службы хранилища (портал Azure) для каждого файла сделайте следующее:

    1. Щелкните правой кнопкой мыши файл и выберите Свойства.
    2. Укажите значение для параметра ContentType и нажмите кнопку Сохранить.

Дополнительные сведения см. в руководстве по размещению статических веб-сайтов в службе хранилища Azure.

Nginx

Следующий файл nginx.conf упрощен для демонстрации того, как настроить Nginx для отправки файла index.html, когда не удается найти соответствующий файл на диске.

events { }
http {
    server {
        listen 80;

        location / {
            root      /usr/share/nginx/html;
            try_files $uri $uri/ /index.html =404;
        }
    }
}

При задании ограничения пиковой скорости NGINX с помощью limit_req приложениям Blazor WebAssembly может потребоваться большое значение параметра burst с учетом сравнительно большого количества запросов, выполняемых приложением. Изначально задайте для этого параметра значение не менее 60.

http {
    server {
        ...

        location / {
            ...

            limit_req zone=one burst=60 nodelay;
        }
    }
}

Увеличьте значение, если средства разработчика в браузере или средство контроля сетевого трафика сообщают о том, что запросы возвращают код состояния 503, служба недоступна.

Дополнительные сведения о конфигурации веб-сервера Nginx в рабочей среде см. в разделе Создание файлов конфигурации NGINX Plus и NGINX.

Apache

Чтобы развернуть приложение Blazor WebAssembly в CentOS 7 или более поздней версии, выполните следующие действия:

  1. Создайте файл конфигурации Apache. В следующем примере показан упрощенный файл конфигурации (blazorapp.config):
<VirtualHost *:80>
    ServerName www.example.com
    ServerAlias *.example.com

    DocumentRoot "/var/www/blazorapp"
    ErrorDocument 404 /index.html

    AddType application/wasm .wasm

    <Directory "/var/www/blazorapp">
        Options -Indexes
        AllowOverride None
    </Directory>

    <IfModule mod_deflate.c>
        AddOutputFilterByType DEFLATE text/css
        AddOutputFilterByType DEFLATE application/javascript
        AddOutputFilterByType DEFLATE text/html
        AddOutputFilterByType DEFLATE application/octet-stream
        AddOutputFilterByType DEFLATE application/wasm
        <IfModule mod_setenvif.c>
      BrowserMatch ^Mozilla/4 gzip-only-text/html
      BrowserMatch ^Mozilla/4.0[678] no-gzip
      BrowserMatch bMSIE !no-gzip !gzip-only-text/html
  </IfModule>
    </IfModule>

    ErrorLog /var/log/httpd/blazorapp-error.log
    CustomLog /var/log/httpd/blazorapp-access.log common
</VirtualHost>
<VirtualHost *:80>
    ServerName www.example.com
    ServerAlias *.example.com

    DocumentRoot "/var/www/blazorapp"
    ErrorDocument 404 /index.html

    AddType application/wasm .wasm
    AddType application/octet-stream .dll

    <Directory "/var/www/blazorapp">
        Options -Indexes
        AllowOverride None
    </Directory>

    <IfModule mod_deflate.c>
        AddOutputFilterByType DEFLATE text/css
        AddOutputFilterByType DEFLATE application/javascript
        AddOutputFilterByType DEFLATE text/html
        AddOutputFilterByType DEFLATE application/octet-stream
        AddOutputFilterByType DEFLATE application/wasm
        <IfModule mod_setenvif.c>
      BrowserMatch ^Mozilla/4 gzip-only-text/html
      BrowserMatch ^Mozilla/4.0[678] no-gzip
      BrowserMatch bMSIE !no-gzip !gzip-only-text/html
  </IfModule>
    </IfModule>

    ErrorLog /var/log/httpd/blazorapp-error.log
    CustomLog /var/log/httpd/blazorapp-access.log common
</VirtualHost>
  1. Поместите файл конфигурации Apache в каталог /etc/httpd/conf.d/. Это каталог конфигурации Apache по умолчанию в CentOS 7.

  2. Поместите файлы приложения в каталог /var/www/blazorapp (расположение, указанное в параметре DocumentRoot в файле конфигурации).

  3. Перезапустите службу Apache.

Дополнительные сведения см. в разделах mod_mime и mod_deflate.

Страницы GitHub

Действие GitHub Actions по умолчанию, которое развертывает страницы и пропускает развертывание папок, начинающихся с символа подчеркивания, например, папки _framework. Чтобы развернуть папки, начинающиеся с символа подчеркивания, добавьте пустой файл .nojekyll в ветвь Git.

Git обрабатывает файлы JavaScript (JS), например blazor.webassembly.js, как текстовые и преобразуют окончание строки из CRLF в LF в конвейере развертывания. Эти изменения в файлах JS создают хэши файлов, которые отличаются от того, что Blazor отправляет клиенту в файле blazor.boot.json. Несоответствия приводят к сбоям проверки целостности на клиенте. Одним из подходов к решению этой проблемы является добавление файла .gitattributes со строкой *.js binary перед добавлением ресурсов приложения в ветвь Git. Строка *.js binary настраивает Git для обработки файлов JS как двоичных файлов, что позволяет избежать обработки файлов в конвейере развертывания. Хэши необработанных файлов соответствуют записям в файле blazor.boot.json, а проверки целостности на стороне клиента выполняются успешно. Дополнительные сведения см. в разделе Устранение ошибок проверки целостности.

Чтобы обеспечить переопределение URL-адресов, добавьте файл wwwroot/404.html со скриптом, который производит перенаправление запроса на страницу index.html. Пример см. в репозитории SteveSandersonMS/BlazorOnGitHubPagesGitHub:

При использовании сайта проекта вместо сайта организации следует обновить тег <base> в файле wwwroot/index.html. Задайте для имени репозитория GitHub значение атрибута href с косой чертой в конце (например, /my-repository/). SteveSandersonMS/BlazorOnGitHubPages В репозитории GitHub база href обновляется при публикации.github/workflows/main.ymlв файле конфигурации.

Примечание.

Репозиторий SteveSandersonMS/BlazorOnGitHubPages GitHub не принадлежит, не поддерживается или поддерживается .NET Foundation или Корпорацией Майкрософт.

Автономное использование Docker

Автономное Blazor WebAssembly приложение публикуется в виде набора статических файлов для размещения статическим файловый сервером.

Чтобы разместить приложение в Docker, выполните следующие действия.

  • Выберите контейнер Docker с поддержкой веб-сервера, например Ngnix или Apache.
  • publish Скопируйте ресурсы папок в папку расположения, определенную на веб-сервере для обслуживания статических файлов.
  • При необходимости примените дополнительную конфигурацию для обслуживания Blazor WebAssembly приложения.

Инструкции по настройке см. в следующих ресурсах:

Значения конфигурации узла

Приложения Blazor WebAssembly могут принимать следующие значения конфигурации узла в качестве аргументов командной строки во время выполнения в среде разработки.

Корневой каталог содержимого

Аргумент --contentroot задает абсолютный путь к каталогу, где находятся файлы содержимого приложения (корневой каталог содержимого). В следующих примерах /content-root-path — это путь к корневому каталогу содержимого приложения.

  • Передайте этот аргумент при локальном запуске приложения в командной строке. Перейдите в каталог приложения и выполните следующую команду:

    dotnet run --contentroot=/content-root-path
    
  • Добавьте запись в файл приложения launchSettings.json в профиле IIS Express. Этот параметр используется при запуске приложения с помощью отладчика Visual Studio и из командной строки вместе с dotnet run.

    "commandLineArgs": "--contentroot=/content-root-path"
    
  • В Visual Studio укажите аргумент в меню Свойства>Отладка>Аргументы приложения. Задание аргумента на странице свойств Visual Studio добавляет его в файл launchSettings.json.

    --contentroot=/content-root-path
    

Базовый путь

Аргумент --pathbase задает базовый путь приложения для локального выполнения с некорневым относительным путем URL (в <base> тег href задан с путем, отличным от / для промежуточной и рабочей сред). В следующих примерах /relative-URL-path — это базовый путь приложения. Дополнительные сведения см. в описании базового пути приложения.

Внимание

В отличие от пути, заданного через href в теге <base>, не ставьте косую черту (/) при передаче значения аргумента --pathbase. Если основной путь приложения задан в теге <base> как <base href="/CoolApp/"> (включая косую черту в конце), передайте значение аргумента командной строки как --pathbase=/CoolApp (без косой черты в конце).

  • Передайте этот аргумент при локальном запуске приложения в командной строке. Перейдите в каталог приложения и выполните следующую команду:

    dotnet run --pathbase=/relative-URL-path
    
  • Добавьте запись в файл приложения launchSettings.json в профиле IIS Express. Этот параметр используется при запуске приложения с помощью отладчика Visual Studio и из командной строки вместе с dotnet run.

    "commandLineArgs": "--pathbase=/relative-URL-path"
    
  • В Visual Studio укажите аргумент в меню Свойства>Отладка>Аргументы приложения. Задание аргумента на странице свойств Visual Studio добавляет его в файл launchSettings.json.

    --pathbase=/relative-URL-path
    

URL-адреса

Аргумент --urls задает IP-адреса или адреса узлов с портами и протоколами, по которым ожидаются запросы.

  • Передайте этот аргумент при локальном запуске приложения в командной строке. Перейдите в каталог приложения и выполните следующую команду:

    dotnet run --urls=http://127.0.0.1:0
    
  • Добавьте запись в файл приложения launchSettings.json в профиле IIS Express. Этот параметр используется при запуске приложения с помощью отладчика Visual Studio и из командной строки вместе с dotnet run.

    "commandLineArgs": "--urls=http://127.0.0.1:0"
    
  • В Visual Studio укажите аргумент в меню Свойства>Отладка>Аргументы приложения. Задание аргумента на странице свойств Visual Studio добавляет его в файл launchSettings.json.

    --urls=http://127.0.0.1:0
    

Размещенное развертывание в Linux (Nginx)

Настройте приложение с ForwardedHeadersOptions для перенаправления заголовков X-Forwarded-For и X-Forwarded-Proto, следуя инструкциям в разделе Настройка ASP.NET Core для работы с прокси-серверами и подсистемами балансировки нагрузки.

Дополнительные сведения о настройке базового пути приложения, включая конфигурацию пути к вложенному приложению, см. в разделе Размещение и развертывание в ASP.NET Core Blazor.

Следуйте указаниям для приложения ASP.NET Core SignalR со следующими изменениями:

  • Удалите конфигурацию для буферизации прокси-сервера (proxy_buffering off;), так как этот параметр применяется только к событиям, отправленным сервером (SSE), которые не относятся к взаимодействию между клиентом и сервером в приложении Blazor.

  • Измените путь location с /hubroute (location /hubroute { ... }) на путь к вложенному приложению /{PATH} (location /{PATH} { ... }), где заполнитель {PATH} является путем к вложенному приложению.

    В следующем примере сервер настраивается для приложения, отвечающего на запросы по корневому пути /:

    http {
        server {
            ...
            location / {
                ...
            }
        }
    }
    

    В следующем примере настраивается путь к вложенному приложению /blazor:

    http {
        server {
            ...
            location /blazor {
                ...
            }
        }
    }
    

Дополнительные сведения и инструкции по настройке см. в следующих ресурсах:

Настройка средства обрезки

Blazor выполняет фильтрацию для промежуточного языка (IL) в каждой сборке выпуска, чтобы удалить ненужный промежуточный язык из выходных сборок. Дополнительные сведения см. в статье Настройка средства обрезки для ASP.NET Core Blazor.

Настройка компоновщика

Blazor выполняет компоновку для промежуточного языка (IL) в каждой сборке выпуска, чтобы удалить ненужный промежуточный язык из выходных сборок. Дополнительные сведения см. в статье Настройка компоновщика для ASP.NET Core Blazor.

Изменение расширения имени файла DLL-файлов

Этот раздел относится к ASP.NET Core 6.x и 7.x. В ASP.NET Core в .NET 8 или более поздней версии сборки .NET развертываются как файлы WebAssembly (.wasm) с помощью формата файла Webcil. В ASP.NET Core в .NET 8 или более поздней версии этот раздел применяется только в том случае, если формат файла Webcil отключен в файле проекта приложения.

Если брандмауэр, антивирусная программа или (модуль) сетевой безопасности блокирует передачу файлов библиотеки динамической компоновки приложения (.dllDLL), вы можете следовать инструкциям в этом разделе, чтобы изменить расширения имен файлов опубликованных DLL-файлов приложения.

Примечание.

Изменение расширений имен файлов DLL приложения может не устранить проблему, так как многие системы безопасности сканируют содержимое файлов приложения, а не просто проверка расширения файлов.

Для более надежного подхода в средах, которые блокируют загрузку и выполнение DLL-файлов, используйте ASP.NET Core в .NET 8 или более поздней версии, которая по умолчанию упаковает сборки .NET в виде файлов WebAssembly (.wasm) с использованием формата файла Webcil . Дополнительные сведения см . в разделе о формате упаковки Webcil для сборок .NET в версии 8.0 или более поздней версии этой статьи.

Сторонние подходы существуют для решения этой проблемы. Дополнительные сведения см. в статье "Удивительный Blazor".

Примечание.

Изменение расширений имен файлов DLL приложения может не устранить проблему, так как многие системы безопасности сканируют содержимое файлов приложения, а не просто проверка расширения файлов.

Для более надежного подхода в средах, которые блокируют загрузку и выполнение DLL-файлов, выполните любой из следующих подходов:

  • Используйте ASP.NET Core в .NET 8 или более поздней версии, которая по умолчанию упаковает сборки .NET в виде файлов WebAssembly (.wasm) с использованием формата файла Webcil . Дополнительные сведения см . в разделе о формате упаковки Webcil для сборок .NET в версии 8.0 или более поздней версии этой статьи.
  • В ASP.NET Core в .NET 6 или более поздней версии используйте пользовательский макет развертывания.

Сторонние подходы существуют для решения этой проблемы. Дополнительные сведения см. в статье "Удивительный Blazor".

После публикации приложения используйте скрипт оболочки или конвейер сборки DevOps для переименования .dll-файлов для использования другого расширения файла в каталоге опубликованных выходных данных приложения.

В примерах ниже сделайте следующее:

  • Для обновления расширений файлов используется PowerShell (PS).
  • Файлы .dll переименовываются с использованием расширения имени файла .bin из командной строки.
  • Файлы, перечисленные в опубликованном файле blazor.boot.json с расширением .dll, обновляются с использованием расширения имени файла .bin.
  • Если ресурсы рабочей роли службы также используются, команда PowerShell обновляет файлы .dll, перечисленные в файле service-worker-assets.js, с использованием расширения имени файла .bin.

Чтобы использовать расширение файла, отличное от .bin, замените .bin в приведенных ниже командах нужным расширением файла.

В Windows:

dir {PATH} | rename-item -NewName { $_.name -replace ".dll\b",".bin" }
((Get-Content {PATH}\blazor.boot.json -Raw) -replace '.dll"','.bin"') | Set-Content {PATH}\blazor.boot.json

В предыдущей команде заполнитель {PATH} — это путь к опубликованной папке _framework (например, .\bin\Release\net6.0\browser-wasm\publish\wwwroot\_framework из корневой папки проекта).

Если ресурсы рабочей роли службы также используются:

((Get-Content {PATH}\service-worker-assets.js -Raw) -replace '.dll"','.bin"') | Set-Content {PATH}\service-worker-assets.js

В предыдущей команде заполнитель {PATH} — это путь к опубликованному файлу service-worker-assets.js.

В Linux или macOS.

for f in {PATH}/*; do mv "$f" "`echo $f | sed -e 's/\.dll/.bin/g'`"; done
sed -i 's/\.dll"/.bin"/g' {PATH}/blazor.boot.json

В предыдущей команде заполнитель {PATH} — это путь к опубликованной папке _framework (например, .\bin\Release\net6.0\browser-wasm\publish\wwwroot\_framework из корневой папки проекта).

Если ресурсы рабочей роли службы также используются:

sed -i 's/\.dll"/.bin"/g' {PATH}/service-worker-assets.js

В предыдущей команде заполнитель {PATH} — это путь к опубликованному файлу service-worker-assets.js.

Для сжатых файлов blazor.boot.json.gz и blazor.boot.json.br используйте один из следующих подходов:

  • Удалите сжатые файлы blazor.boot.json.gz и blazor.boot.json.br. Сжатие отключено с помощью этого подхода.
  • Выполните повторное сжатие обновленного файла blazor.boot.json.

Приведенные выше рекомендации для сжатого файла blazor.boot.json также применимы при использовании ресурсов рабочей роли службы. Выполните удаление или повторное сжатие файлов service-worker-assets.js.br и service-worker-assets.js.gz. иначе проверка целостности файлов в браузере завершится ошибкой.

В следующем примере Windows для .NET 6 используется сценарий PowerShell, размещенный в корне проекта. Следующий сценарий, который отключает сжатие, является основой для дальнейшего изменения, если вы хотите повторно сжать файл blazor.boot.json.

ChangeDLLExtensions.ps1::

param([string]$filepath,[string]$tfm)
dir $filepath\bin\Release\$tfm\browser-wasm\publish\wwwroot\_framework | rename-item -NewName { $_.name -replace ".dll\b",".bin" }
((Get-Content $filepath\bin\Release\$tfm\browser-wasm\publish\wwwroot\_framework\blazor.boot.json -Raw) -replace '.dll"','.bin"') | Set-Content $filepath\bin\Release\$tfm\browser-wasm\publish\wwwroot\_framework\blazor.boot.json
Remove-Item $filepath\bin\Release\$tfm\browser-wasm\publish\wwwroot\_framework\blazor.boot.json.gz
Remove-Item $filepath\bin\Release\$tfm\browser-wasm\publish\wwwroot\_framework\blazor.boot.json.br

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

((Get-Content $filepath\bin\Release\$tfm\browser-wasm\publish\wwwroot\service-worker-assets.js -Raw) -replace '.dll"','.bin"') | Set-Content $filepath\bin\Release\$tfm\browser-wasm\publish\wwwroot\_framework\wwwroot\service-worker-assets.js
Remove-Item $filepath\bin\Release\$tfm\browser-wasm\publish\wwwroot\_framework\wwwroot\service-worker-assets.js.gz
Remove-Item $filepath\bin\Release\$tfm\browser-wasm\publish\wwwroot\_framework\wwwroot\service-worker-assets.js.br

В файле проекта скрипт выполняется после публикации приложения для конфигурации Release:

<Target Name="ChangeDLLFileExtensions" AfterTargets="AfterPublish" Condition="'$(Configuration)'=='Release'">
  <Exec Command="powershell.exe -command &quot;&amp; { .\ChangeDLLExtensions.ps1 '$(SolutionDir)' '$(TargetFramework)'}&quot;" />
</Target>

Примечание.

При переименовании и отложенной загрузке одних и тех же сборок см. статью Сборки с отложенной загрузкой в ASP.NET Core Blazor WebAssembly.

Как правило, серверу приложения требуется настройка статического ресурса для обслуживания файлов с обновленным расширением. Для приложения, размещенного службами IIS, добавьте запись карты MIME (<mimeMap>) для нового расширения файла в разделе статического содержимого (<staticContent>) в пользовательском web.config файле. В следующем примере предполагается, что расширение файла изменено на .dll.bin:

<staticContent>
  ...
  <mimeMap fileExtension=".bin" mimeType="application/octet-stream" />
  ...
</staticContent>

Включите обновление для сжатых файлов, если сжатие используется:

<mimeMap fileExtension=".bin.br" mimeType="application/octet-stream" />
<mimeMap fileExtension=".bin.gz" mimeType="application/octet-stream" />

Удалите запись для .dll расширения файла:

- <mimeMap fileExtension=".dll" mimeType="application/octet-stream" />

Удалите записи для сжатых .dll файлов, если сжатие используется:

- <mimeMap fileExtension=".dll.br" mimeType="application/octet-stream" />
- <mimeMap fileExtension=".dll.gz" mimeType="application/octet-stream" />

Дополнительные сведения о пользовательских web.config файлах см. в разделе "Использование пользовательского web.config ".

Повреждение до развертывания

Обычно при развертывании:

  • Заменяются только измененные файлы, что обычно приводит к ускорению развертывания.
  • Существующие файлы, не являющиеся частью нового развертывания, остаются на месте для использования в новом развертывании.

В редких случаях устаревшие файлы из предыдущих развертываний могут повредить новое развертывание. Полное удаление существующего развертывания (или локально опубликованного приложения до развертывания) может устранить проблему с поврежденным развертыванием. Часто для устранения проблемы достаточно удалить существующее развертывание однократно, в том числе для конвейера сборки и развертывания DevOps.

Если вы определили, что очистка до развертывания всегда требуется при использовании конвейера сборки и развертывания DevOps, можно временно добавить шаг в конвейер сборки, чтобы удалить прежнее развертывание для каждого нового развертывания, пока не будет устранена точная причина повреждения.

Устранение проблем с проверкой целостности

Когда Blazor WebAssembly скачивает файлы запуска для приложения, браузеру получает инструкции выполнить проверку целостности для ответов. Blazor отправляет хэш-значения SHA-256 для DLL (.dll), WebAssembly (.wasm) и других файлов в файле blazor.boot.json, который не кэшируется в клиентах. Хэши кэшированных файлов сравниваются с хэшами в файле blazor.boot.json. Для кэшированных файлов с совпадающим хэшем Blazor использует кэшированные файлы. В противном случае файлы запрашиваются с сервера. После скачивания файла его хэш снова проверяется на целостность. Браузер генерирует ошибку, если проверка целостности скачанного файла не удалась.

Алгоритм Blazor для управления целостностью файлов:

  • Гарантирует, что приложение не будет загружать несогласованный набор файлов, например, если новое развертывание применяется к вашему веб-серверу, пока пользователь скачивает файлы приложения. Использование несогласованных файлов может привести к неправильной работе приложения.
  • Гарантирует, что браузер пользователя никогда не будет кэшировать несогласованные или недопустимые ответы, что может помешать запуску приложения, даже если пользователь вручную обновляет страницу.
  • Делает безопасным кэширование ответов и не проверяет изменения на стороне сервера до тех пор, пока не изменятся сами ожидаемые хэши SHA-256, поэтому последующие загрузки страниц включают меньше запросов и выполняются быстрее.

Если веб-сервер возвращает ответы, не соответствующие ожидаемым хэшам SHA-256, в консоли разработчика браузера отобразится примерно такая ошибка:

Failed to find a valid digest in the 'integrity' attribute for resource 'https://myapp.example.com/_framework/MyBlazorApp.dll' with computed SHA-256 integrity 'IIa70iwvmEg5WiDV17OpQ5eCztNYqL186J56852RpJY='. Ресурс заблокирован.

В большинстве случаев предупреждение не указывает на проблему с проверкой целостности. Вместо этого предупреждение обычно означает, что существует другая проблема.

Справочный источник загрузки Blazor WebAssembly доступен в файле Boot.WebAssembly.ts в репозитории dotnet/aspnetcore в GitHub.

Примечание.

По ссылкам в документации на справочные материалы по .NET обычно загружается ветвь репозитория по умолчанию, которая представляет текущую разработку для следующего выпуска .NET. Чтобы выбрать тег для определенного выпуска, используйте раскрывающийся список Switch branches or tags (Переключение ветвей или тегов). Дополнительные сведения см. в статье Выбор тега версии исходного кода ASP.NET Core (dotnet/AspNetCore.Docs #26205).

Диагностика проблем целостности

При создании приложения сгенерированный манифест blazor.boot.json описывает хэши SHA-256 ваших ресурсов загрузки на момент создания выходных данных сборки. Проверка целостности проходит успешно до тех пор, пока хэши SHA-256 в blazor.boot.json соответствуют переданным в браузер файлам.

Распространенные причины сбоя:

  • Веб-сервер возвращает не запрошенный браузером файл, а информацию об ошибке (например, 404 - Not Found (не найдено) или 500 - Internal Server Error (внутренняя ошибка сервера)). В браузере этот ответ проявляется как ошибка проверки целостности, но не как ошибка ответа.
  • Содержимое файлов по какой-либо причине изменилось в период между их сборкой и доставкой в браузер. Это может произойти:
    • Если вы вручную или с помощью средств сборки изменили выходные данные сборки.
    • Если какие-то аспекты процесса развертывания изменили файлы. Например, при использовании механизма развертывания на основе Git важно помнить, что Git прозрачно преобразует концы строк из стиля Windows в стиль UNIX, если вы фиксируете файлы из Windows, а затем получаете их в Linux. Изменение концов строк в файле приводит к изменению хэша SHA-256. Чтобы избежать этой проблемы, можно применить .gitattributes, чтобы артефакты сборки воспринимались как файлы binary;
    • Если веб-сервер изменяет содержимое файла при его обработке. Например, некоторые сети доставки содержимого (CDN) автоматически пытаются уменьшить размер HTML-файлов, неизбежно изменяя их. Возможно, вам придется отключить эти функции.
  • Файл blazor.boot.json не загружается должным образом или неправильно кэшируется в клиенте. Распространенные причины включают одно из следующих причин:
    • Неправильно настроенный или неисправный пользовательский код разработчика.
    • Один или несколько неправильно настроенных промежуточных уровней кэширования.

Чтобы определить причину для конкретной ситуации, сделайте следующее.

  1. Узнайте, какой файл вызывает ошибку, прочитав сообщение об ошибке.
  2. Откройте средства разработчика браузера и перейдите на вкладку "Сеть ". При необходимости перезагрузите страницу, чтобы просмотреть список запросов и ответов. Найдите в этом списке файл, который вызвал ошибку.
  3. Проверьте код состояния в ответе HTTP. Если сервер возвращает любой ответ, кроме 200 — OK или другого кода из диапазона 2xx, значит проблему нужно диагностировать на стороне сервера. Например, код состояния 403 означает проблему с авторизацией, а код состояния 500 — неопределенную ошибку в работе сервера. Просмотрите журналы на стороне сервера, чтобы диагностировать и исправить приложение.
  4. Если для ресурса возвращается код состояния 200 — ОK, проверьте содержимое ответа с помощью средств разработчика в браузере и убедитесь, что это содержимое соответствует ожиданиям. Например, довольно часто ошибка в настройке маршрутизации приводит к тому, что запросы возвращают страницу index.html даже при обращении к другим файлам. Убедитесь, что в ответ на запросы .wasm возвращаются двоичные файлы WebAssembly, а в ответ на запросы .dll — двоичные файлы сборки .NET. В противном случае проблему нужно диагностировать на стороне сервера.
  5. Попытайтесь проверить выходные данные опубликованного и развернутого приложения с помощью скрипта PowerShell для устранения проблем целостности.

Если вы убедились, что сервер возвращает данные в предположительно правильном формате, значит что-то еще изменяет содержимое файлов в период между сборкой и доставкой. Для анализа этой ситуации сделайте следующее:

  • Изучите цепочку инструментов сборки и механизм развертывания, чтобы исключить операции изменения файлов после сборки. Выше описан пример таких изменений, связанный с преобразованием концов строк в файлах при работе с Git.
  • Изучите конфигурацию веб-сервера или сети доставки содержимого, чтобы исключить динамическое изменение ответов в них (например, для уменьшения размера HTML-файлов). При этом сжатие HTTP (например, в формате content-encoding: br или content-encoding: gzip) на стороне веб-сервера считается допустимым, так как не влияет на результат после распаковки. Но совершенно недопустимы изменения несжатых данных на веб-сервере.

Скрипт PowerShell для устранения проблем целостности

Используйте в PowerShell скрипт integrity.ps1 для проверки опубликованного и развернутого приложения Blazor. Скрипт предоставляется для PowerShell Core 7 или более поздней версии в качестве начальной точки, если в приложении есть проблемы с целостностью, которые платформа Blazor не может распознать. Для приложений может потребоваться настройка скрипта, в том числе при запуске в PowerShell более поздней версии, чем версия 7.2.0.

Скрипт проверяет файлы, расположенные в папке publish и скачанные из развернутого приложения, чтобы обнаружить проблемы в разных манифестах, содержащих хэши целостности. При этих проверках должны быть обнаружены наиболее распространенные проблемы:

  • Вы изменили файл в опубликованных выходных данных, не зная этого.
  • Приложение было неправильно развернуто в целевом объекте развертывания или что-то изменилось в среде целевого объекта развертывания.
  • Данные развернутого приложения и выходные данные публикации приложения отличаются.

Вызовите скрипт в командной оболочке PowerShell с помощью следующей команды:

.\integrity.ps1 {BASE URL} {PUBLISH OUTPUT FOLDER}

В следующем примере сценарий выполняется в локально запущенном приложении в https://localhost:5001/:

.\integrity.ps1 https://localhost:5001/ C:\TestApps\BlazorSample\bin\Release\net6.0\publish\

Заполнители:

  • {BASE URL}: URL-адрес развернутого приложения. Требуется завершающая косая черта (/).
  • {PUBLISH OUTPUT FOLDER}: Путь к папке или расположению приложения publish , в котором приложение публикуется для развертывания.

Примечание.

При клонировании репозитория GitHub dotnet/AspNetCore.Docs скрипт integrity.ps1 может быть помещен в карантин программой Bitdefender или другой программой поиска вирусов, присутствующей в системе. Обычно файл перехватывается технологией эвристического сканирования программы поиска вирусов, которая просто ищет в файлах шаблоны, которые могут указывать на присутствие вредоносных программ. Чтобы программа поиска вирусов не поместила файл в карантин, добавьте исключение в программу перед клонированием репозитория. Ниже представлен типичный путь к скрипту для системы Windows. При необходимости измените путь для других систем. Заполнитель {USER} — это сегмент пути пользователя.

C:\Users\{USER}\Documents\GitHub\AspNetCore.Docs\aspnetcore\blazor\host-and-deploy\webassembly\_samples\integrity.ps1

Предупреждение.Создавать исключения в программе поиска вирусов опасно. Это можно делать, только если вы уверены, что файл безопасен.

Успешное сравнение контрольной суммы файла с допустимым значением контрольной суммы не гарантирует, что файл безопасен. Но изменение файла для обеспечения соответствия со значением контрольной суммы является непростой задачей для злоумышленников. Поэтому контрольные суммы полезны как общий подход к обеспечению безопасности. Сравните контрольную сумму локального файла integrity.ps1 с одним из приведенных ниже значений.

  • SHA256: 32c24cb667d79a701135cb72f6bae490d81703323f61b8af2c7e5e5dc0f0c2bb
  • MD5: 9cee7d7ec86ee809a329b5406fbf21a8

Получите контрольную сумму файла в ОС Windows с помощью указанной ниже команды. Укажите путь и имя файла для заполнителя {PATH AND FILE NAME}, а также тип контрольной суммы, которую нужно создать для заполнителя {SHA512|MD5}, SHA256 или MD5:

CertUtil -hashfile {PATH AND FILE NAME} {SHA256|MD5}

Если у вас есть основания опасаться, что проверка контрольной суммы недостаточно безопасна в вашем окружении, обратитесь к руководству по безопасности организации.

Дополнительные сведения см. в разделе "Обзор защиты от угроз с помощью антивирусная программа в Microsoft Defender".

Отключение проверки целостности для приложений, не относящихся к PWA

В большинстве случаев проверку целостности отключать не нужно. Отключение проверки целостности не решает основную проблему, которая вызывает непредвиденные ответы, и приводит к потере описанных выше преимуществ.

Могут быть случаи, когда веб-сервер не может возвращать согласованные ответы, и у вас нет других вариантов, кроме как временно отключить проверки целостности, пока основная проблема не будет решена.

Для этого добавьте следующий фрагмент в группу свойств в файле проекта .csproj приложения Blazor WebAssembly:

<BlazorCacheBootResources>false</BlazorCacheBootResources>

BlazorCacheBootResources также отключает Blazorповедение кэширования по умолчанию для .dll, .wasm и других файлов на основе хэшей SHA-256, так как это свойство запрещает доверять правильности хэшей SHA-256. Даже при включенном параметре стандартный кэш HTTP браузера может кэшировать эти файлы, но этим поведением можно управлять через конфигурацию веб-сервера и заголовков cache-control, которые он возвращает.

Примечание.

Свойство BlazorCacheBootResources не отключает проверку целостности для прогрессивных веб-приложений (PWA). Сведения об особенностях работы с PWA см. в разделе Отключение проверки целостности для PWA.

Мы не можем предоставить исчерпывающий список сценариев, в которых требуется отключение проверки целостности. Серверы могут отвечать на запрос произвольным образом, что выходит за рамки платформы Blazor. Платформа предоставляет параметр BlazorCacheBootResources, чтобы сделать приложение работоспособным за счет потери гарантии целостности, которую может предоставить приложение. Опять же, мы не рекомендуем отключать проверку целостности, особенно для производственных развертываний. Разработчики должны стремиться решить основную проблему с целостностью, которая приводит к сбою проверки целостности.

Несколько общих сценариев, которые могут вызвать проблемы с целостностью:

  • Выполнение через HTTP, когда нельзя проверить целостность.
  • Если ваш процесс развертывания каким-либо образом изменяет файлы после публикации.
  • Если ваш узел каким-либо образом изменяет файлы.

Отключение проверки целостности для PWA

Шаблон Blazor для прогрессивного веб-приложения (PWA) содержит рекомендуемый файл service-worker.published.js, который отвечает за получение и хранение файлов приложений для автономного использования. Этот процесс отличается от обычного механизма запуска приложения и использует собственную логику проверки целостности.

В файле service-worker.published.js есть следующая строка:

.map(asset => new Request(asset.url, { integrity: asset.hash }));

Чтобы отключить проверку целостности, удалите параметр integrity из этой строки, заменив ее следующим текстом:

.map(asset => new Request(asset.url));

И в этом случае отключение проверки целостности будет означать потерю гарантий безопасности, которые предоставляет этот механизм. Например, появится риск кэширования приложения в браузере пользователя в тот момент, когда развертывается новая версия. При этом могут кэшироваться файлы одновременно из старого и нового развертываний. В такой ситуации приложение окажется неработоспособным до развертывания следующего обновления.

SignalRКонфигурация

SignalRУсловия размещения и масштабирования применяются к Blazor приложениям, которые используют SignalR.

Транспорты

В качестве транспортного механизма SignalR для Blazor лучше всего подходит WebSocket благодаря низкой задержке, хорошей надежности и улучшенной безопасности. SignalR использует продолжительный опрос, если это настроено в приложении явным образом или подключения WebSocket недоступны. При развертывании Службы приложений Azure настройте приложение на использование WebSocket в параметрах службы на портале Azure. Подробные сведения о настройке приложения для Службы приложений Azure см. в статье с рекомендациями по публикации приложения SignalR.

Появится предупреждение консоли, если используется длинный опрос:

Не удалось подключиться через WebSocket, используется резервный транспортный механизм длительного опроса. Это может быть связано с тем, что подключение блокируется каналом VPN или прокси-сервером.

Глобальные сбои развертывания и подключения

Рекомендации для глобальных развертываний в географических центрах обработки данных:

  • Разверните приложение в регионах, где проживает большинство пользователей.
  • Учитывайте повышенную задержку трафика на разных континентах.
  • Для размещения Azure используйте службу AzureSignalR.

Если развернутое приложение часто отображает пользовательский интерфейс повторного подключения из-за времени ожидания связи, вызванных задержкой в Интернете, устраните время ожидания сервера и клиента:

  • Сервер

    По крайней мере удвоите максимальное время круглого обхода между клиентом и сервером. Тестирование, мониторинг и изменение времени ожидания по мере необходимости. Для концентратора SignalR задайте ClientTimeoutInterval (по умолчанию: 30 секунд) и HandshakeTimeout (по умолчанию: 15 секунд). В следующем примере предполагается, что KeepAliveInterval используется значение по умолчанию 15 секунд.

    Внимание

    Он KeepAliveInterval не связан напрямую с отображаемым пользовательским интерфейсом повторного подключения. Интервал "Сохранить в живых" не обязательно должен быть изменен. Если проблема с появлением пользовательского интерфейса повторного подключения возникает из-за времени ожидания, это может быть увеличено, ClientTimeoutIntervalHandshakeTimeout а интервал "Сохранить в живых" может оставаться неизменным. Важно учитывать, что при изменении интервала "Сохранение активности" убедитесь, что значение времени ожидания клиента не менее двойное значение интервала "Сохранить в живых" и что интервал "Сохранить в живых" на клиенте соответствует параметру сервера.

    В следующем примере ClientTimeoutInterval увеличивается до 60 секунд и HandshakeTimeout увеличивается до 30 секунд.

    Program В файле серверного приложения:

    builder.Services.AddSignalR(options =>
    {
         options.ClientTimeoutInterval = TimeSpan.FromSeconds(60);
         options.HandshakeTimeout = TimeSpan.FromSeconds(30);
    });
    

    Дополнительные сведения см. в статье Руководство по ASP.NET Core BlazorSignalR.

  • Клиент

    Как правило, удвоите значение, используемое для сервера KeepAliveInterval , чтобы задать время ожидания для времени ожидания сервера клиента (ServerTimeoutпо умолчанию: 30 секунд).

    Внимание

    ИнтервалKeepAliveInterval сохранения активности () не связан напрямую с отображаемым пользовательским интерфейсом повторного подключения. Интервал "Сохранить в живых" не обязательно должен быть изменен. Если проблема с появлением пользовательского интерфейса повторного подключения возникает из-за времени ожидания, время ожидания сервера может быть увеличено, а интервал "Сохранить в живых" может оставаться неизменным. Важно учитывать, что при изменении интервала "Сохранить в живых" убедитесь, что значение времени ожидания по крайней мере удвоит значение интервала "Сохранить в живых" и что интервал "Сохранить в живых" на сервере соответствует параметру клиента.

    При создании подключения концентратора в компоненте можно настроить ServerTimeout значения (по умолчанию: 30 секунд) и HandshakeTimeout (по умолчанию: 15 секунд).

    В следующем примере время ожидания сервера увеличивается до 60 секунд, а время ожидания подтверждения увеличивается до 30 секунд:

protected override async Task OnInitializedAsync()
{
    hubConnection = new HubConnectionBuilder()
        .WithUrl(Navigation.ToAbsoluteUri("/chathub"))
        .WithServerTimeout(TimeSpan.FromSeconds(60))
        .Build();

    hubConnection.HandshakeTimeout = TimeSpan.FromSeconds(30);

    hubConnection.On<string, string>("ReceiveMessage", (user, message) => ...

    await hubConnection.StartAsync();
}
protected override async Task OnInitializedAsync()
{
    hubConnection = new HubConnectionBuilder()
        .WithUrl(Navigation.ToAbsoluteUri("/chathub"))
        .Build();

    hubConnection.ServerTimeout = TimeSpan.FromSeconds(60);
    hubConnection.HandshakeTimeout = TimeSpan.FromSeconds(30);

    hubConnection.On<string, string>("ReceiveMessage", (user, message) => ...

    await hubConnection.StartAsync();
}

При изменении значений времени ожидания сервера (ServerTimeout) или интервала поддержания активности (KeepAliveInterval:

  • Время ожидания сервера должно быть по крайней мере двойным значением, назначенным интервалу keep-Alive.
  • Интервал "Сохранить в режиме жизни" должен быть меньше или равен половине значения, назначенного времени ожидания сервера.

Дополнительные сведения см. в статье Руководство по ASP.NET Core BlazorSignalR.