JavaScript-Speicherort in ASP.NET Core-Apps Blazor

Hinweis

Dies ist nicht die neueste Version dieses Artikels. Informationen zum aktuellen Release finden Sie in der .NET 8-Version dieses Artikels.

Wichtig

Diese Informationen beziehen sich auf ein Vorabversionsprodukt, das vor der kommerziellen Freigabe möglicherweise noch wesentlichen Änderungen unterliegt. Microsoft gibt keine Garantie, weder ausdrücklich noch impliziert, hinsichtlich der hier bereitgestellten Informationen.

Informationen zum aktuellen Release finden Sie in der .NET 8-Version dieses Artikels.

Laden Sie JavaScript-(JS)-Code mit einem der folgenden Ansätze:

Warnung

Platzieren Sie ein <script>-Tag nur in einer Komponentendatei (.razor), wenn die Komponente garantiert statisches serverseitiges Rendering (static sSR) verwendet, da das <script>-Tag nicht dynamisch aktualisiert werden kann.

Warnung

Platzieren Sie kein <script>-Tag in einer Komponentendatei (.razor), weil das <script>-Tag nicht dynamisch aktualisiert werden kann.

Hinweis

Dokumentationsbeispiele platzieren Skripts in der Regel in einem <script>-Tag oder laden globale Skripts aus externen Dateien. Mit diesen Ansätzen wird der Client mit globalen Funktionen belastet. Für Produktions-Apps empfehlen wir, JS in separate JSModule zu platzieren, die bei Bedarf importiert werden können. Weitere Informationen finden Sie im Abschnitt JavaScript-Isolation in JavaScript-Modulen.

Hinweis

Dokumentationsbeispiele platzieren Skripts in einem <script>-Tag oder laden globale Skripts aus externen Dateien. Mit diesen Ansätzen wird der Client mit globalen Funktionen belastet. Das Platzieren von JS in separate JS Module, die bei Bedarf importiert werden können, wird vor ASP.NET Core 5.0 Blazornicht unterstützt. Wenn die App die Verwendung von JS Modulen für JS die Isolation erfordert, wird empfohlen, ASP.NET Core 5.0 oder höher zu verwenden, um die App zu erstellen. Weitere Informationen finden Sie in der Dropdownliste derVersion, um eine Version 5.0 oder höher dieses Artikels auszuwählen. Sehen Sie zudem den Abschnitt JavaScript-Isolation in JavaScript-Modulen.

Laden eines Skripts im <head>-Markup

Der Ansatz in diesem Abschnitt wird im Allgemeinen nicht empfohlen.

Platzieren Sie die Tags <script>...</script> von JavaScript (JS) im Markup des <head>-Elements:

<head>
    ...

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

Das Laden von JS aus <head> ist aus den folgenden Gründen nicht der beste Ansatz:

  • JS Interop kann fehlschlagen, wenn das Skript von Blazor abhängt. Es wird empfohlen, Skripts mit einem der anderen Ansätze zu laden, nicht über das <head>-Markup.
  • Die Seite kann aufgrund der Zeit, die zum Analysieren von JS im Skript benötigt wird, interaktiv langsamer werden.

Laden eines Skripts im <body>-Markup

Platzieren Sie die JavaScript-Tags (<script>...</script>) innerhalb des schließende </body> -Elements, nach der Skriptreferenz Blazor :

<body>
    ...

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

Im vorangegangenen Beispiel entspricht der {BLAZOR SCRIPT}-Platzhalter dem Pfad und Dateinamen des Blazor-Skripts. Informationen zum Speicherort des Skripts finden Sie unter Projektstruktur für ASP.NET Core Blazor.

Laden eines Skripts aus einer externen JavaScript-Datei (.js), die mit einer Komponente angeordnet ist

Die Kombination von JavaScript-Dateien (JS) für Razor-Komponenten ist praktisch, um Skripts in einer App zu organisieren.

Razor-Komponenten von Blazor-Apps kombinieren JS-Dateien mithilfe der .razor.js-Erweiterung und können öffentlich mithilfe des Pfads zur Datei im Projekt adressiert werden:

{PATH}/{COMPONENT}.razor.js

  • Der Platzhalter {PATH} ist der Pfad zur Komponente.
  • Der Platzhalter {COMPONENT} ist die Komponente.

Wenn die App veröffentlicht wird, verschiebt das Framework das Skript automatisch in den Webstamm. Skripts werden in bin/Release/{TARGET FRAMEWORK MONIKER}/publish/wwwroot/{PATH}/{COMPONENT}.razor.js verschoben. Die folgenden Platzhalter werden verwendet:

Es ist keine Änderung an der relativen URL des Skripts erforderlich, da Blazor die JS-Datei für Sie in den veröffentlichten statischen Ressourcen platziert.

Dieser Abschnitt und die folgenden Beispiele konzentrieren sich hauptsächlich auf die Erläuterung der Kombination von JS-Dateien. Im ersten Beispiel wird eine kombinierte JS-Datei mit einer gewöhnlichen JS-Funktion veranschaulicht. Im zweiten Beispiel wird die Verwendung eines Moduls zum Laden von Funktionen veranschaulicht. Dieser Ansatz wird für die meisten Produktions-Apps empfohlen. Das Aufrufen von JS über .NET wird vollständig in Aufrufen von JavaScript-Funktionen aus .NET-Methoden in ASP.NET Core Blazor behandelt, wo weitere Erläuterungen zur BlazorJS-API mit zusätzlichen Beispielen vorhanden sind. Die Komponentenlöschung, die im zweiten Beispiel erfolgt, wird unter Lebenszyklus von ASP.NET Core Razor-Komponenten behandelt.

Die folgende JsCollocation1-Komponente lädt ein Skript über eine HeadContent-Komponente und ruft eine JS-Funktion mit IJSRuntime.InvokeAsync auf. Der Platzhalter {PATH} ist der Pfad zur Komponente.

Wichtig

Wenn Sie den folgenden Code für eine Demonstration in einer Test-App verwenden, ändern Sie den Platzhalter {PATH} in den Pfad der Komponente (Beispiel: Components/Pages in .NET 8 oder höher oder Pages in .NET 7 oder früher). In einer Blazor-Web-App (.NET 8 oder höher) benötigt die Komponente einen interaktiven Rendermodus, der entweder global auf die App oder auf die Komponentendefinition angewendet wird.

Fügen Sie das folgende Skript nach dem Blazor-Skript (-Speicherort des Blazor-Startskripts) hinzu:

<script src="{PATH}/JsCollocation1.razor.js"></script>

JsCollocation1-Komponente ({PATH}/JsCollocation1.razor):

@page "/js-collocation-1"
@inject IJSRuntime JS

<PageTitle>JS Collocation 1</PageTitle>

<h1>JS Collocation Example 1</h1>

<button @onclick="ShowPrompt">Call showPrompt1</button>

@if (!string.IsNullOrEmpty(result))
{
    <p>
        Hello @result!
    </p>
}

@code {
    private string? result;

    public async void ShowPrompt()
    {
        result = await JS.InvokeAsync<string>(
            "showPrompt1", "What's your name?");
        StateHasChanged();
    }
}

Die kombinierte JS-Datei wird neben der JsCollocation1-Komponentendatei mit dem Dateinamen JsCollocation1.razor.js platziert. In der JsCollocation1-Komponente wird im Pfad der kombinierten Datei auf das Skript verwiesen. Im folgenden Beispiel akzeptiert die showPrompt1-Funktion den Benutzernamen aus Window prompt() und gibt ihn zur Anzeige an die JsCollocation1-Komponente zurück.

{PATH}/JsCollocation1.razor.js:

function showPrompt1(message) {
  return prompt(message, 'Type your name here');
}

Der vorstehende Ansatz wird nicht für die allgemeine Verwendung in Produktions-Apps empfohlen, da er den Client mit globalen Funktionen verunreinigt. Ein besserer Ansatz für Produktions-Apps besteht darin, JS-Module zu verwenden. Die gleichen allgemeinen Prinzipien gelten für das Laden eines JS-Moduls aus einer kombinierten JS-Datei, wie das nächste Beispiel zeigt.

Mit der OnAfterRenderAsync-Methode der folgenden JsCollocation2-Komponente wird ein JS-Modul in module geladen, bei dem es sich um ein IJSObjectReference-Element der Komponentenklasse handelt. module wird verwendet, um die showPrompt2-Funktion aufzurufen. Der Platzhalter {PATH} ist der Pfad zur Komponente.

Wichtig

Wenn Sie den folgenden Code für eine Demonstration in einer Test-App verwenden, ändern Sie den Platzhalter {PATH} in den Pfad der Komponente. In einer Blazor-Web-App (.NET 8 oder höher) benötigt die Komponente einen interaktiven Rendermodus, der entweder global auf die App oder auf die Komponentendefinition angewendet wird.

JsCollocation2-Komponente ({PATH}/JsCollocation2.razor):

@page "/js-collocation-2"
@implements IAsyncDisposable
@inject IJSRuntime JS

<PageTitle>JS Collocation 2</PageTitle>

<h1>JS Collocation Example 2</h1>

<button @onclick="ShowPrompt">Call showPrompt2</button>

@if (!string.IsNullOrEmpty(result))
{
    <p>
        Hello @result!
    </p>
}

@code {
    private IJSObjectReference? module;
    private string? result;

    protected async override Task OnAfterRenderAsync(bool firstRender)
    {
        if (firstRender)
        {
            /*
                Change the {PATH} placeholder in the next line to the path of
                the collocated JS file in the app. Examples:

                ./Components/Pages/JsCollocation2.razor.js (.NET 8 or later)
                ./Pages/JsCollocation2.razor.js (.NET 7 or earlier)
            */
            module = await JS.InvokeAsync<IJSObjectReference>("import",
                "./{PATH}/JsCollocation2.razor.js");
        }
    }

    public async void ShowPrompt()
    {
        if (module is not null)
        {
            result = await module.InvokeAsync<string>(
                "showPrompt2", "What's your name?");
            StateHasChanged();
        }
    }

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

{PATH}/JsCollocation2.razor.js:

export function showPrompt2(message) {
  return prompt(message, 'Type your name here');
}

Für Skripts oder Module, die von einer Razor-Klassenbibliothek (RCL) bereitgestellt werden, wird der folgende Pfad verwendet:

_content/{PACKAGE ID}/{PATH}/{COMPONENT}.{EXTENSION}.js

  • Der Platzhalter {PACKAGE ID} ist der Paketbezeichner der RCL (oder der Bibliotheksname für eine Klassenbibliothek, auf die von der App verwiesen wird).
  • Der Platzhalter {PATH} ist der Pfad zur Komponente. Wenn sich eine Razor-Komponente im Stammverzeichnis der RCL befindet, wird das Pfadsegment nicht eingeschlossen.
  • Der Platzhalter {COMPONENT} ist der Komponentenname.
  • Der Platzhalter {EXTENSION} entspricht der Erweiterung der Komponente, also razor oder cshtml.

Im folgenden Beispiel für die Blazor-App gilt:

  • Der Paketbezeichner der RCL ist AppJS.
  • Die Skripts eines Moduls werden für die Komponente JsCollocation3 (JsCollocation3.razor) geladen.
  • Die Komponente JsCollocation3 befindet sich im Components/Pages-Ordner der RCL.
module = await JS.InvokeAsync<IJSObjectReference>("import", 
    "./_content/AppJS/Components/Pages/JsCollocation3.razor.js");

Weitere Informationen zu RCLs finden Sie unter Nutzen von ASP.NET Core Razor-Komponenten über eine Razor-Klassenbibliothek (RCL).

Laden eines Skripts aus einer externen JavaScript-Datei (.js)

Platzieren Sie die Tags <script>...</script> von JavaScript (JS) mit einem Skriptquellenpfad (src) innerhalb des schließenden </body>-Elements nach dem Blazor-Skriptverweis:

<body>
    ...

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

Im vorherigen Beispiel:

  • Der Platzhalter {BLAZOR SCRIPT} entspricht dem Blazor-Skriptpfad und -Dateinamen. Informationen zum Speicherort des Skripts finden Sie unter Projektstruktur für ASP.NET Core Blazor.
  • Der {SCRIPT PATH AND FILE NAME (.js)}-Platzhalter ist der Pfad- und Skript-Dateiname unter wwwroot.

Im folgenden Beispiel des vorangehenden <script>-Tags befindet sich die scripts.js-Datei im wwwroot/js-Ordner der App:

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

Sie können Skripts auch direkt aus dem Ordner wwwroot bereitstellen, wenn Sie nicht alle Ihre Skripts in einem separaten Ordner unter wwwroot aufbewahren möchten:

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

Wenn die externe JS-Datei von einer Razor Klassenbibliothek bereitgestellt wird, geben Sie die JS-Datei mithilfe ihres stabilen statischen Web-Ressourcenpfads an: ./_content/{PACKAGE ID}/{SCRIPT PATH AND FILE NAME (.js)}:

  • Das Pfadsegment für das aktuelle Verzeichnis (./) ist erforderlich, damit der korrekte Pfad zu statischen Objekten in der JS-Datei erstellt werden kann.
  • Der Platzhalter {PACKAGE ID} ist diePaket-IDder Bibliothek. Die Paket-ID wird standardmäßig auf den Assemblynamen des Projekts festgelegt, wenn <PackageId> nicht in der Projektdatei angegeben ist.
  • Der Platzhalter {SCRIPT PATH AND FILE NAME (.js)} entspricht dem Pfad und Dateinamen unter wwwroot.
<body>
    ...

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

Im folgenden Beispiel des vorangehenden <script>-Tags:

  • Die Klassenbibliothek Razor hat den Assembly-Namen ComponentLibrary, und ein <PackageId> ist nicht in der Projektdatei der Bibliothek angegeben.
  • Die scripts.js-Datei befindet sich im wwwroot-Ordner der Klassenbibliothek.
<script src="./_content/ComponentLibrary/scripts.js"></script>

Weitere Informationen finden Sie unter Nutzen von ASP.NET Core Razor-Komponenten über eine Razor-Klassenbibliothek (RCL).

Einfügen eines Skripts vor oder nach dem Start von Blazor

Verwenden Sie einen JavaScript-Initialisierer, um sicherzustellen, dass Skripts vor oder nach dem Start von Blazor geladen werden. Weitere Informationen und Beispiele finden Sie im Artikel „Starten von ASP.NET Core Blazor“ unter JavaScript-Initialisierer.

Einfügen eines Skripts nach dem Starten von Blazor

Wenn Sie ein Skript einfügen möchten, nachdem Blazor gestartet wurde, verketten Sie es mit der Zusage (Promise), die aus einem manuellen Start von Blazor resultiert. Weitere Informationen und ein Beispiel finden Sie unter Starten von ASP.NET Core Blazor.

JavaScript-Isolierung in JavaScript-Modulen

Blazor aktiviert die JavaScript-Isolation (JS) in StandardJS-Modulen (ECMAScript-Spezifikation).

JS-Isolierung bietet die folgenden Vorteile:

  • Importiertes JS verschmutzt nicht mehr den globalen Namespace.
  • Consumer einer Bibliothek und Komponenten müssen nicht das zugehörige JS importieren.

Weitere Informationen finden Sie unter Aufrufen von JavaScript-Funktionen über .NET-Methoden in Blazor in ASP.NET Core.

Der dynamische Import mit dem import()-Operator wird mit ASP.NET Core und Blazor unterstützt:

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

Im vorherigen Beispiel steht der Platzhalter {CONDITION} für eine bedingte Überprüfung, mit der festgestellt wird, ob das Modul geladen werden soll.

Informationen zur Browserkompatibilität finden Sie unter Can I use: JavaScript modules: dynamic import.