ASP.NET Core Blazor JavaScript の相互運用性 (JS 相互運用)

Note

これは、この記事の最新バージョンではありません。 現在のリリースについては、この記事の .NET 8 バージョンを参照してください。

この記事では、Blazor アプリで JavaScript とやりとりする方法について一般的な概念を説明します。

Blazor アプリでは、.NET メソッドから JavaScript (JS) 関数を呼び出すことも、JS 関数から .NET メソッドを呼び出すこともできます。 これらのシナリオは、"JavaScript 相互運用性" ("JS 相互運用") と呼ばれます。

JS 相互運用の詳細なガイダンスについては、後の記事で説明されています。

Note

JavaScript [JSImport]/[JSExport] 相互運用 API は、ASP.NET Core 7.0 以降のクライアント側コンポーネントで使用できます。

詳細については、「ASP.NET Core Blazor を使用した JavaScript JSImport/JSExport 相互運用」を参照してください。

この記事では、アプリ コードが実行される場所を区別するために、クライアント/クライアント側サーバー/サーバー側という用語が使用されます。

  • クライアント/クライアント側
    • Blazor Web アプリのクライアント側レンダリング (CSR)。 Program ファイルはクライアント プロジェクト (.Client) の Program.cs です。 Blazor スクリプトの開始構成は、サーバー プロジェクの App コンポーネント (Components/App.razor) にあります。 @page ディレクティブを持つルーティング可能な対話型 WebAssembly および対話型自動レンダリング モード コンポーネントは、クライアント プロジェクトの Pages フォルダーに配置されます。 ルーティング不可能な共有コンポーネントは、.Client プロジェクトのルート、またはコンポーネントの機能に基づいてカスタム フォルダーに配置します。
    • Blazor WebAssembly アプリ。 Program ファイルは Program.cs です。 Blazor スクリプトの開始構成は wwwroot/index.html ファイルにあります。
  • サーバー/サーバー側: Blazor Web アプリの対話型サーバー側レンダリング (対話型 SSR)。 Program ファイルは、サーバー プロジェクトの Program.cs です。 Blazor スクリプトの開始構成は App コンポーネント (Components/App.razor) にあります。 Components/Pages フォルダーに配置されるのは、@page ディレクティブを持つルーティング可能な対話型サーバー レンダリング モード コンポーネントのみです。 ルーティング不可能な共有コンポーネントは、サーバー プロジェクトの Components フォルダーに配置されます。 必要に応じて、コンポーネントの機能に基づいてカスタム フォルダーを作成します。
  • クライアント/クライアント側
    • ホスト型 Blazor WebAssembly アプリの Client プロジェクト。
    • Blazor WebAssembly アプリ。
    • Blazor スクリプトの開始構成は wwwroot/index.html ファイルにあります。
    • Program ファイルは Program.cs です。
  • サーバー/サーバー側
    • ホスト型 Blazor WebAssembly アプリの Server プロジェクト。
    • Blazor Server アプリ。 Blazor スクリプトの開始構成は Pages/_Host.cshtml にあります。
    • Program ファイルは Program.cs です。
  • クライアント/クライアント側
    • ホスト型 Blazor WebAssembly アプリの Client プロジェクト。
    • Blazor WebAssembly アプリ。
    • Blazor スクリプトの開始構成は wwwroot/index.html ファイルにあります。
    • Program ファイルは Program.cs です。
  • サーバー/サーバー側
    • ホスト型 Blazor WebAssembly アプリの Server プロジェクト。
    • Blazor Server アプリ。 Blazor スクリプトの開始構成は Pages/_Layout.cshtml にあります。
    • Program ファイルは Program.cs です。
  • クライアント/クライアント側
    • ホスト型 Blazor WebAssembly アプリの Client プロジェクト。
    • Blazor WebAssembly アプリ。
    • Blazor スクリプトの開始構成は wwwroot/index.html ファイルにあります。
    • Program ファイルは Program.cs です。
  • サーバー/サーバー側
    • ホスト型 Blazor WebAssembly アプリの Server プロジェクト。
    • Blazor Server アプリ。 Blazor スクリプトの開始構成は Pages/_Host.cshtml にあります。
    • Program ファイルは Program.cs です。

JavaScript 相互運用抽象化および機能パッケージ

@microsoft/dotnet-js-interop パッケージ (npmjs.com) は、.NET コードと JavaScript (JS) コード間の相互運用のための抽象化と機能を提供します。 参照ソースは dotnet/aspnetcoreGitHub リポジトリ (/src/JSInterop フォルダー) で入手できます。 詳細については、GitHub リポジトリのREADME.md ファイルを参照してください。

Note

通常、.NET 参照ソースへのドキュメント リンクを使用すると、リポジトリの既定のブランチが読み込まれます。このブランチは、.NET の次回リリースに向けて行われている現在の開発を表します。 特定のリリースのタグを選択するには、[Switch branches or tags](ブランチまたはタグの切り替え) ドロップダウン リストを使います。 詳細については、「ASP.NET Core ソース コードのバージョン タグを選択する方法」 (dotnet/AspNetCore.Docs #26205) を参照してください。

TypeScript で JS 相互運用スクリプトを作成するための追加リソース:

DOM の操作

オブジェクトが Blazor と対話しない場合にのみ、JavaScript (JS) を使用して DOM を変換します。 Blazor は、DOM の表現を維持し、DOM オブジェクトと直接対話します。 Blazor によってレンダリングされた要素が JS を直接使用して、または JS 相互運用機能を使用して外部で変更された場合、DOM は Blazor の内部表現と一致しなくなり、未定義の動作が生じることがあります。 未定義の動作は、要素またはその機能の表示を妨げる​​だけでなく、アプリまたはサーバーにセキュリティ リスクをもたらす可能性もあります。

このガイダンスは、独自の JS 相互運用コードだけでなく、アプリが使用する JS ライブラリにも適用されます。これには、BootstrapJSjQuery などのサードパーティ製のフレームワークによって提供されるものも含まれます。

いくつかのドキュメントの例では、例の一部として、JS 相互運用機能を使用して要素を単なるデモンストレーションの目的で変換します。 そのような場合は、テキストに警告が表示されます。

詳しくは、「ASP.NET Core Blazor で .NET メソッドから JavaScript 関数を呼び出す」をご覧ください。

非同期 JavaScript 呼び出し

JS 相互運用呼び出しは、呼び出されたコードが同期であるか非同期であるかに関係なく、既定で非同期となります。 呼び出しが既定で非同期であるのは、サーバー側とクライアント側のレンダリング モデルでコンポーネントの互換性を確保するためです。 サーバー側レンダリングを採用する場合、JS 相互運用呼び出しはネットワーク接続を介して送信されるため、非同期である必要があります。 クライアント側レンダリングのみを採用するアプリの場合、同期 JS 相互運用呼び出しがサポートされます。

オブジェクトのシリアル化

Blazor では、次の要件と既定の動作でシリアル化に System.Text.Json を使用します。

  • 型には既定のコンストラクターが必要です。get/set アクセサーはパブリックである必要があります。フィールドはシリアル化されません。
  • グローバルな既定のシリアル化は、既存のコンポーネント ライブラリの破損、パフォーマンスとセキュリティへの影響、信頼性の低下を回避するためにカスタマイズできません。
  • .NET メンバー名をシリアル化すると、小文字の JSON キー名になります。
  • JSON は、大文字と小文字の混在が許可される、JsonElement C# インスタンスとして逆シリアル化されます。 C# モデル プロパティへの割り当ての内部キャストは、JSON キー名と C# プロパティ名の間に大文字と小文字の違いがあっても、期待したとおりに動作します。

JsonConverter API は、カスタム シリアル化に使用できます。 プロパティに [JsonConverter] 属性の注釈を付けて、既存のデータ型の既定のシリアル化をオーバーライドできます。

詳細については、.NET ドキュメントの次のリソースを参照してください。

Blazor では、Base64 へのバイト配列のエンコードおよびデコードを回避する、最適化されたバイト配列 JS 相互運用がサポートされています。 アプリで、カスタム シリアル化を適用し、結果のバイトを渡すことができます。 詳しくは、「ASP.NET Core Blazor で .NET メソッドから JavaScript 関数を呼び出す」をご覧ください。

Blazor では、大量の .NET オブジェクトが急速にシリアル化される場合、または大きな .NET オブジェクトまたは多数の .NET オブジェクトをシリアル化する必要がある場合に、マーシャリングされていない JS 相互運用がサポートされます。 詳しくは、「ASP.NET Core Blazor で .NET メソッドから JavaScript 関数を呼び出す」をご覧ください。

コンポーネントの破棄中の DOM クリーンアップ タスク

コンポーネントの破棄の間に、DOM クリーンアップ タスクに対して JS 相互運用コードを実行しないでください。 代わりに、次の理由により、クライアント上の JavaScript (JS) で MutationObserver パターンを使用してください。

  • クリーンアップ コードが Dispose{Async} で実行されるまでに、コンポーネントが DOM から削除されている可能性があります。
  • サーバー側のレンダリング中、クリーンアップ コードが Dispose{Async} で実行されるまでに、Blazor レンダラーがフレームワークによって破棄されている可能性があります。

MutationObserver パターンを使うと、DOM から要素が削除されていても関数を実行できます。

次の例では、DOMCleanup コンポーネントは次のようになります。

  • cleanupDivid を持つ <div> が含まれています。 <div> 要素は、コンポーネントが DOM から削除されるときに、コンポーネントの残りの DOM マークアップとともに DOM から削除されます。
  • DOMCleanup.razor.js ファイルから DOMCleanupJS クラスを読み込みし、その createObserver 関数を呼び出して MutationObserver コールバックを設定します。 これらのタスクは、OnAfterRenderAsync ライフサイクル メソッド で実行されます。

DOMCleanup.razor:

@page "/dom-cleanup"
@rendermode InteractiveServer
@implements IAsyncDisposable
@inject IJSRuntime JS

<h1>DOM Cleanup Example</h1>

<div id="cleanupDiv"></div>

@code {
    private IJSObjectReference? jsModule;

    protected override async Task OnAfterRenderAsync(bool firstRender)
    {
        if (firstRender)
        {
            jsModule = await JS.InvokeAsync<IJSObjectReference>(
                "import", "./Components/Pages/DOMCleanup.razor.js");

            await jsModule.InvokeVoidAsync("DOMCleanup.createObserver");
        }
    }

    async ValueTask IAsyncDisposable.DisposeAsync()
    {
        if (jsModule is not null)
        {
            await jsModule.DisposeAsync();
        }
    }
}
@page "/dom-cleanup"
@implements IAsyncDisposable
@inject IJSRuntime JS

<h1>DOM Cleanup Example</h1>

<div id="cleanupDiv"></div>

@code {
    private IJSObjectReference? jsModule;

    protected override async Task OnAfterRenderAsync(bool firstRender)
    {
        if (firstRender)
        {
            jsModule = await JS.InvokeAsync<IJSObjectReference>(
                "import", "./Pages/DOMCleanup.razor.js");

            await jsModule.InvokeVoidAsync("DOMCleanup.createObserver");
        }
    }

    async ValueTask IAsyncDisposable.DisposeAsync()
    {
        if (jsModule is not null)
        {
            await jsModule.DisposeAsync();
        }
    }
}

次の例では、DOM 変更が発生するたびに MutationObserver コールバックが実行されます。 if ステートメントによってターゲット要素 (cleanupDiv) が削除されたことが確認されたら、クリーンアップ コードを実行します (if (targetRemoved) { ... })。 クリーンアップ コードの実行後にメモリ リークを避けるために、MutationObserver を切断して削除することが重要です。

DOMCleanup.razor.js は、前述の DOMCleanup コンポーネントと並べて配置されます。

export class DOMCleanup {
  static observer;

  static createObserver() {
    const target = document.querySelector('#cleanupDiv');

    this.observer = new MutationObserver(function (mutations) {
      const targetRemoved = mutations.some(function (mutation) {
        const nodes = Array.from(mutation.removedNodes);
        return nodes.indexOf(target) !== -1;
      });

      if (targetRemoved) {
        // Cleanup resources here
        // ...

        // Disconnect and delete MutationObserver
        this.observer && this.observer.disconnect();
        delete this.observer;
      }
    });

    this.observer.observe(target.parentNode, { childList: true });
  }
}

window.DOMCleanup = DOMCleanup;

回線を使用しない JavaScript 相互運用呼び出し

このセクションはサーバー側アプリにのみ適用されます。

JavaScript (JS) 相互運用呼び出しは、SignalR 回線が切断された後は発行できません。 コンポーネントの破棄中に回線がない、または回線が存在しないその他の時点で、次のメソッド呼び出しは失敗し、回線が切断されたというメッセージが JSDisconnectedException としてログされます。

JSDisconnectedException のログを回避したり、カスタム情報をログしたりするには、try-catch ステートメントで例外をキャッチします。

次のコンポーネント破棄の例で:

  • コンポーネントでは IAsyncDisposable を実装します。
  • objInstanceIJSObjectReference です。
  • JSDisconnectedException がキャッチされ、ログはされません。
  • 必要に応じて、任意のログ レベルで catch ステートメントにカスタム情報をログできます。 次の例では、コンポーネントの破棄中にいつ、どこで回線が切断されるかを開発者が気にしないことを前提としているため、カスタム情報はログされません。
async ValueTask IAsyncDisposable.DisposeAsync()
{
    try
    {
        if (objInstance is not null)
        {
            await objInstance.DisposeAsync();
        }
    }
    catch (JSDisconnectedException)
    {
    }
}

回線が失われた後に、独自の JS オブジェクトをクリーンアップするか、クライアントで他の JS のコードを実行する必要がある場合は、クライアントの JS で MutationObserver のパターンを使用します。 MutationObserver パターンを使うと、DOM から要素が削除されていても関数を実行できます。

詳細については、次の記事を参照してください。

JavaScript の場所

JavaScript (JS) のコードを読み込むには、次のいずれかの方法を使用します。

警告

<script> タグは Blazor で動的に更新できないため、<script> タグを Razor コンポーネント ファイル (.razor) 内に配置しないでください。

Note

ドキュメントの例では、通常、スクリプトを <script> タグに配置するか、または外部ファイルからグローバル スクリプトを読み込みます。 これらの方法では、グローバル関数でクライアントが汚染されます。 運用アプリの場合は、必要に応じてインポートできる別の JavaScript モジュールに JavaScript を配置することをお勧めします。 詳細については、「JavaScript モジュールでの JavaScript の分離」セクションを参照してください。

Note

ドキュメントの例では、<script> タグにスクリプトを配置するか、または外部ファイルからグローバル スクリプトを読み込みます。 これらの方法では、グローバル関数でクライアントが汚染されます。 必要に応じてインポートできる別の JavaScript モジュールへの JavaScript の配置は、ASP.NET Core 5.0 より前の Blazor ではサポートされていません。 アプリで JS の分離のために JS モジュールを使用する必要がある場合は、ASP.NET Core 5.0 以降を使用してアプリをビルドすることをお勧めします。 詳細については、[バージョン] ドロップダウン リストを使用して、この記事の 5.0 以降のバージョンを選択し、「JavaScript モジュールでの JavaScript の分離」セクションを参照してください。

<head> マークアップでスクリプトを読み込む

このセクションのアプローチは、一般的には推奨されていません。

JavaScript (JS) タグ (<script>...</script>) を<head>要素マークアップに配置します。

<head>
    ...

    <script>
      window.jsMethod = (methodParameter) => {
        ...
      };
    </script>
</head>

<head> から JS を読み込むことは、次の理由により最適な方法ではありません。

  • スクリプトが Blazor に依存している場合、JS 相互運用が失敗するおそれがあります。 <head> マークアップではなく、他の方法のいずれかを使用してスクリプトを読み込むことをお勧めします。
  • スクリプト内で JS を解析するのに時間がかかるため、ページの動作が遅くなることがあります。

<body> マークアップでスクリプトを読み込む

Blazor スクリプト参照の後の終了</body>要素内に JavaScript (JS) タグ (<script>...</script>) を配置します。

<body>
    ...

    <script src="{BLAZOR SCRIPT}"></script>
    <script>
      window.jsMethod = (methodParameter) => {
        ...
      };
    </script>
</body>

前の例の {BLAZOR SCRIPT} プレースホルダーは、Blazor スクリプトのパスとファイル名です。 スクリプトの場所については、「ASP.NET Core Blazor プロジェクトの構造」を参照してください。

コンポーネントと同じ場所に存在する外部 JavaScript ファイル (.js) からスクリプトを読み込む

ページ、ビュー、Razor コンポーネントのための JavaScript (JS) ファイルの併置は、アプリでスクリプトを整理する便利な方法です。

JS ファイルを併置するには、次のファイル名拡張子の規則を使用します。

  • Razor Pages アプリのページと MVC アプリのビュー: .cshtml.js。 例:
    • Pages/Index.cshtml にある Razor Pages アプリの Index ページに対する Pages/Index.cshtml.js
    • Views/Home/Index.cshtml にある MVC アプリの Index ビューに対する Views/Home/Index.cshtml.js
  • Blazor アプリの Razor コンポーネント: .razor.js。 例: Index コンポーネントの場合は Index.razor.js

併置された JS ファイルは、"プロジェクト内のファイルへのパス" を使用してパブリックにアドレス指定できます。

  • アプリ内の併置されたスクリプト ファイルからのページ、ビュー、コンポーネント:

    {PATH}/{PAGE, VIEW, OR COMPONENT}.{EXTENSION}.js

    • {PATH} プレースホルダーは、ページ、ビュー、またはコンポーネントへのパスです。
    • {PAGE, VIEW, OR COMPONENT} プレースホルダーは、ページ、ビュー、またはコンポーネントです。
    • {EXTENSION} プレースホルダーは、ページ、ビュー、またはコンポーネントの拡張子 (razor または cshtml) と一致します。

    Razor ページの例:

    Index ページの JS ファイルは、Index ページ (Pages/Index.cshtml) と共に Pages フォルダー (Pages/Index.cshtml.js) に配置されます。 Index ページでは、スクリプトは Pages フォルダー内のパスで参照されます。

    @section Scripts {
      <script src="~/Pages/Index.cshtml.js"></script>
    }
    

    アプリが公開されると、スクリプトはフレームワークによって Web ルートに自動的に移動されます。 前の例では、スクリプトは bin\Release\{TARGET FRAMEWORK MONIKER}\publish\wwwroot\Pages\Index.cshtml.js に移動されます。{TARGET FRAMEWORK MONIKER} プレースホルダーはターゲット フレームワーク モニカー (TFM) です。 Index ページ内のスクリプトの相対 URL を変更する必要はありません。

    Blazor の例:

    Index コンポーネントの JS ファイルは、Index コンポーネント (Index.razor) の横に配置されます。 Index コンポーネントでは、スクリプトはそのパスで参照されます。

    Index.razor.js:

    export function showPrompt(message) {
      return prompt(message, 'Type anything here');
    }
    

    Index コンポーネント (Index.razor) の OnAfterRenderAsync メソッド:

    module = await JS.InvokeAsync<IJSObjectReference>(
        "import", "./Components/Pages/Index.razor.js");
    

    アプリが公開されると、スクリプトはフレームワークによって Web ルートに自動的に移動されます。 前の例では、スクリプトは bin\Release\{TARGET FRAMEWORK MONIKER}\publish\wwwroot\Components\Pages\Index.razor.js に移動されます。{TARGET FRAMEWORK MONIKER} プレースホルダーはターゲット フレームワーク モニカー (TFM) です。 Index コンポーネント内のスクリプトの相対 URL を変更する必要はありません。

  • Razor クラス ライブラリ (RCL) によって提供されるスクリプトの場合:

    _content/{PACKAGE ID}/{PATH}/{PAGE, VIEW, OR COMPONENT}.{EXTENSION}.js

    • {PACKAGE ID} プレースホルダーは、RCL のパッケージ識別子 (または、アプリによって参照されるクラス ライブラリのライブラリ名) です。
    • {PATH} プレースホルダーは、ページ、ビュー、またはコンポーネントへのパスです。 Razor コンポーネントが RCL のルートにある場合、パス セグメントは含まれません。
    • {PAGE, VIEW, OR COMPONENT} プレースホルダーは、ページ、ビュー、またはコンポーネントです。
    • {EXTENSION} プレースホルダーは、ページ、ビュー、またはコンポーネントの拡張子 (razor または cshtml) と一致します。

    次の Blazor アプリの例の場合:

    • RCL のパッケージ識別子は AppJS です。
    • モジュールのスクリプトは、Index コンポーネント (Index.razor) に対して読み込まれます。
    • Index コンポーネントは、RCL の Components フォルダーの Pages フォルダー内にあります。
    var module = await JS.InvokeAsync<IJSObjectReference>("import", 
        "./_content/AppJS/Components/Pages/Index.razor.js");
    

RCL の詳細については、「ASP.NET Core Razor コンポーネントを Razor クラス ライブラリから使用する」を参照してください。

外部 JavaScript ファイル (.js) からスクリプトを読み込む

Blazor スクリプト参照の後の終了</body>要素内に、スクリプト ソース (src) パスを使用して JavaScript (JS) のタグ (<script>...</script>) を配置します。

<body>
    ...

    <script src="{BLAZOR SCRIPT}"></script>
    <script src="{SCRIPT PATH AND FILE NAME (.js)}"></script>
</body>

前の例の場合:

  • {BLAZOR SCRIPT} プレースホルダーは、Blazor スクリプトのパスとファイル名です。 スクリプトの場所については、「ASP.NET Core Blazor プロジェクトの構造」を参照してください。
  • {SCRIPT PATH AND FILE NAME (.js)} プレースホルダーは、wwwroot の下のパスとスクリプト ファイル名です。

上記の <script> タグの次の例では、scripts.js ファイルはアプリの wwwroot/js フォルダーにあります。

<script src="js/scripts.js"></script>

すべてのスクリプトを wwwroot の下の別のフォルダーに保存したくない場合は、wwwroot フォルダーから直接スクリプトを提供することもできます。

<script src="scripts.js"></script>

Razor クラス ライブラリによって外部の JS ファイルが提供される場合は、安定した静的 Web アセット パス ./_content/{PACKAGE ID}/{SCRIPT PATH AND FILE NAME (.js)} を使用して JS ファイルを指定します。

  • JS ファイルへの正しい静的アセット パスを作成するためには、現在のディレクトリ (./) に対するパス セグメントが必要です。
  • {PACKAGE ID} プレースホルダーは、ライブラリのパッケージ ID です。 プロジェクト ファイルで <PackageId> が指定されていない場合、パッケージ ID の既定値はプロジェクトのアセンブリ名になります。
  • {SCRIPT PATH AND FILE NAME (.js)} プレースホルダーは、wwwroot の下のパスとファイル名です。
<body>
    ...

    <script src="{BLAZOR SCRIPT}"></script>
    <script src="./_content/{PACKAGE ID}/{SCRIPT PATH AND FILE NAME (.js)}"></script>
</body>

上記の <script> タグの例を次に示します。

  • Razor クラス ライブラリのアセンブリ名は ComponentLibrary であり、<PackageId> はライブラリのプロジェクト ファイルで指定されません。
  • scripts.js ファイルは、クラス ライブラリの wwwroot フォルダーにあります。
<script src="./_content/ComponentLibrary/scripts.js"></script>

詳細については、「ASP.NET Core Razor コンポーネントを Razor クラス ライブラリから使用する」を参照してください。

Blazor の開始前または開始後にスクリプトを挿入する

Blazor の開始前または開始後にスクリプトが確実に読み込まれるようにするには、JavaScript 初期化子を使用します。 詳細と例については、「ASP.NET Core のBlazor起動」を参照してください。

Blazor の開始後にスクリプトを挿入する

Blazor の開始後にスクリプトを挿入するには、Blazor を手動で開始した結果の Promise にチェーンします。 詳細と例については、「ASP.NET Core のBlazor起動」を参照してください。

JavaScript モジュールでの JavaScript の分離

Blazor では、標準の Blazorに JavaScript (JS) を分離できます (JS)。

JS を分離すると、次のようなベネフィットがあります。

  • インポートされる JS によって、グローバル名前空間が汚染されなくなります。
  • ライブラリおよびコンポーネントのコンシューマーは、関連する JS をインポートする必要がありません。

詳しくは、「ASP.NET Core Blazor で .NET メソッドから JavaScript 関数を呼び出す」をご覧ください。

import() 演算子を使用した動的インポートは、ASP.NET Core と Blazorでサポートされています。

if ({CONDITION}) import("/additionalModule.js");

前述の例では、プレースホルダー {CONDITION} は、モジュールを読み込む必要があるかどうかを判断するための条件付きチェックを表しています。

ブラウザーの互換性については、「Can I use: JavaScript modules: dynamic import (使用できるかどうか: JavaScript モジュール: dynamic import)」を参照してください。

キャッシュされた JavaScript ファイル

JavaScript (JS) ファイルおよびその他の静的資産は、通常、Development 環境での開発中にクライアントにキャッシュされません。 開発中、静的資産要求には、値が no-cacheCache-Control ヘッダー、または値がゼロ (0) の max-age が含まれます。

Production 環境での運用中は、通常、JS ファイルはクライアントによってキャッシュされます。

ブラウザーでクライアント側のキャッシュを無効にするには、通常、開発者は次のいずれかのアプローチを採用します。

  • ブラウザーの開発者ツール コンソールが開いているときにキャッシュを無効にします。 ガイダンスについては、各ブラウザー メンテナンス ツールの開発者ツール ドキュメントを参照してください。
  • Blazor アプリの Web ページをブラウザーで手動で更新して、サーバーから JS ファイルを再読み込みします。 ASP.NET Core の HTTP キャッシング ミドルウェアでは、クライアントによって送信された有効なキャッシュなし Cache-Control ヘッダーが常に優先されます。

詳細については、以下を参照してください:

JavaScript 相互運用呼び出しのサイズ制限

このセクションは、サーバー側アプリの対話型コンポーネントにのみ適用されます。 クライアント側コンポーネントの場合、フレームワークは JavaScript (JS) 相互運用入力および出力のサイズに制限を課しません。

サーバー側アプリの対話型コンポーネントの場合、クライアントからサーバーにデータを渡す JS 相互運用呼び出しのサイズは、ハブ メソッドに許可される受信 SignalR メッセージの最大サイズによって制限され、これは HubOptions.MaximumReceiveMessageSize によって強制されます (既定値: 32 KB)。 JS から .NET への SignalR メッセージが MaximumReceiveMessageSize より大きい場合は、エラーがスローされます。 このフレームワークでは、ハブからクライアントへの SignalR メッセージのサイズが制限されることはありません。 サイズ制限、エラー メッセージ、メッセージ サイズ制限に対処するためのガイダンスの詳細については、「ASP.NET Core BlazorSignalRガイダンス」を参照してください。

アプリが実行されている場所を決定する

アプリが JS 相互運用呼び出しでコードが実行されている場所を知る必要がある場合は、OperatingSystem.IsBrowser を使用して WebAssembly 上のブラウザーのコンテキストでコンポーネントが実行されているかどうかを判断します。