Udostępnij za pośrednictwem


Współdziałanie języka JavaScript platformy ASP.NET Core Blazor (współdziałanie języka JS)

Uwaga

Nie jest to najnowsza wersja tego artykułu. Aby zapoznać się z bieżącą wersją, zobacz wersję tego artykułu platformy .NET 9.

Ostrzeżenie

Ta wersja ASP.NET Core nie jest już obsługiwana. Aby uzyskać więcej informacji, zobacz zasady pomocy technicznej platformy .NET i platformy .NET Core. Aby zapoznać się z bieżącą wersją, zobacz wersję tego artykułu platformy .NET 9.

Ważne

Te informacje odnoszą się do produktu w wersji wstępnej, który może zostać znacząco zmodyfikowany, zanim zostanie wydany komercyjnie. Firma Microsoft nie udziela żadnych gwarancji, jawnych lub domniemanych, w odniesieniu do informacji podanych w tym miejscu.

Aby zapoznać się z bieżącą wersją, zobacz wersję tego artykułu platformy .NET 9.

Aplikacja platformy Blazor może wywoływać funkcje języka JavaScript (JS) z metod platformy .NET oraz metody platformy.NET z funkcji języka JS. Te scenariusze są nazywane współdziałaniem języka JavaScript (współdziałaniem języka JS).

Dalsze wskazówki dotyczące współdziałania języka JS są dostępne w następujących artykułach:

Uwaga

Interfejs API międzyoperacyjny języka JavaScript [JSImport]/[JSExport] jest dostępny dla składników po stronie klienta w programie ASP.NET Core na platformie .NET 7 lub nowszym.

Aby uzyskać więcej informacji, zobacz JavaScript JSImport/JSExport interop with ASP.NET Core (Interopcja javaScript JSImport/JSExport with ASP.NET Core Blazor).

Kompresja składników interakcyjnych serwerów z niezaufanymi danymi

Dzięki kompresji, która jest domyślnie włączona, unikaj tworzenia bezpiecznych (uwierzytelnionych/autoryzowanych) interaktywnych składników po stronie serwera, które renderuje dane z niezaufanych źródeł. Niezaufane źródła obejmują parametry trasy, ciągi zapytań, dane z JS międzyoperacyjności i inne źródło danych, które użytkownik innej firmy może kontrolować (bazy danych, usługi zewnętrzne). Aby uzyskać więcej informacji, zobacz ASP.NET Core guidance and Threat mitigation guidance for ASP.NET Core interactive server-side rendering (Wskazówki ASP.NET CoreSignalR Blazordotyczące ograniczania zagrożeń dotyczące interaktywnego renderowania po stronie serwera ASP.NET CoreBlazor).

Abstrakcji międzyoperacyjnych i pakietów funkcji języka JavaScript

Pakiet @microsoft/dotnet-js-interop (npmjs.com) (Microsoft.JSInterop pakiet NuGet) udostępnia abstrakcję i funkcje między kodem .NET i JavaScript (JS). Źródło referencyjne jest dostępne w dotnet/aspnetcore repozytorium GitHub (/src/JSInterop folder). Aby uzyskać więcej informacji, zobacz plik repozytorium README.md GitHub.

Uwaga

Linki dokumentacji do źródła referencyjnego platformy .NET zwykle ładują domyślną gałąź repozytorium, która odzwierciedla bieżące programowanie dla następnej wersji platformy .NET. Aby wybrać tag dla określonej wersji, użyj listy rozwijanej Przełącz gałęzie lub tagi. Aby uzyskać więcej informacji, zobacz Jak wybrać tag wersji kodu źródłowego platformy ASP.NET Core (dotnet/AspNetCore.Docs #26205).

Dodatkowe zasoby do pisania JS skryptów międzyoperacyjności w języku TypeScript:

Interakcja z dom

Zmutuj dom tylko przy użyciu języka JavaScript (JS), gdy obiekt nie wchodzi w interakcję z elementem Blazor. Platforma Blazor utrzymuje reprezentacje modelu DOM i współdziała bezpośrednio z obiektami modelu DOM. Jeśli element renderowany przez platformę Blazor jest modyfikowany zewnętrznie przy użyciu języka JS bezpośrednio lub przez współdziałanie języka JS, model DOM może być już niezgodny z wewnętrzną reprezentacją platformy Blazor, co może spowodować niezdefiniowane zachowanie. Niezdefiniowane zachowanie może tylko zakłócać prezentację elementów lub ich funkcji, ale może również powodować zagrożenia bezpieczeństwa dla aplikacji lub serwera.

Te wskazówki dotyczą nie tylko własnego kodu współdziałania języka JS, ale także wszystkich bibliotek języka JS używanych przez aplikację, w tym wszystkich elementów udostępnianych przez platformę innej firmy, takich jak Bootstrap JS i jQuery.

W kilku przykładach dokumentacji współdziałanie języka JS jest używane do modyfikowania elementu wyłącznie do celów demonstracyjnych w ramach przykładu. W takich przypadkach w tekście pojawia się ostrzeżenie.

Aby uzyskać więcej informacji, zobacz Wywoływanie funkcji języka JavaScript z metod platformy .NET na platformie ASP.NET Core Blazor.

Klasa JavaScript z polem funkcji typu

Klasa Języka JavaScript z polem funkcji typu nie jest obsługiwana przez BlazorJS międzyoperację. Używanie funkcji Języka JavaScript w klasach.

Nieobsługiwane: GreetingHelpers.sayHello w następującej klasie jako pole funkcji typu nie jest wykrywane przez Blazormiędzyoperacyjności JS i nie można wykonać z kodu C#:

export class GreetingHelpers {
  sayHello = function() {
    ...
  }
}

Obsługiwane: GreetingHelpers.sayHello w następującej klasie jako funkcja jest obsługiwana:

export class GreetingHelpers {
  sayHello() {
    ...
  }
}

Obsługiwane są również funkcje strzałek:

export class GreetingHelpers {
  sayHello = () => {
    ...
  }
}

Unikaj wbudowanych programów obsługi zdarzeń

Funkcję JavaScript można wywołać bezpośrednio z wbudowanej procedury obsługi zdarzeń. W poniższym przykładzie alertUser jest funkcją Języka JavaScript wywoływaną po wybraniu przycisku przez użytkownika:

<button onclick="alertUser">Click Me!</button>

Jednak użycie wbudowanych procedur obsługi zdarzeń jest złym wyborem w przypadku wywoływania funkcji języka JavaScript:

  • Mieszanie znaczników HTML i kodu JavaScript często prowadzi do niezamierzonego kodu.
  • Wykonywanie wbudowanego programu obsługi zdarzeń może zostać zablokowane przez dokumentację zasad zabezpieczeń zawartości (CSP) (MDN).

Zalecamy unikanie wbudowanych procedur obsługi zdarzeń na rzecz podejść, które przypisują programy obsługi w języku JavaScript za pomocą addEventListenermetody , jak pokazano w poniższym przykładzie:

AlertUser.razor.js:

export function alertUser() {
  alert('The button was selected!');
}

export function addHandlers() {
  const btn = document.getElementById("btn");
  btn.addEventListener("click", alertUser);
}

AlertUser.razor:

@page "/alert-user"
@implements IAsyncDisposable
@inject IJSRuntime JS

<h1>Alert User</h1>

<p>
    <button id="btn">Click Me!</button>
</p>

@code {
    private IJSObjectReference? module;

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

            await module.InvokeVoidAsync("addHandlers");
        }
    }

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

W poprzednim przykładzie JSDisconnectedException jest uwięziony podczas usuwania modułu w przypadku Blazorutraty obwodu SignalR . Jeśli poprzedni kod jest używany w Blazor WebAssembly aplikacji, nie ma SignalR połączenia do utraty, więc możesz usunąćcatch try-blok i pozostawić wiersz, który usuwa moduł ().await module.DisposeAsync(); Aby uzyskać więcej informacji, zobacz ASP.NET Core Blazor JavaScript interoperability (JS interop).

Aby uzyskać więcej informacji, zobacz następujące zasoby:

Asynchroniczne wywołania języka JavaScript

JS wywołania międzyoperacyjne są asynchroniczne, niezależnie od tego, czy wywoływany kod jest synchroniczny, czy asynchroniczny. Wywołania są asynchroniczne, aby upewnić się, że składniki są zgodne z modelami renderowania po stronie serwera i po stronie klienta. Podczas wdrażania renderowania po stronie serwera wywołania międzyoperacyjne muszą być asynchroniczne, JS ponieważ są wysyłane za pośrednictwem połączenia sieciowego. W przypadku aplikacji, które korzystają wyłącznie z renderowania po stronie klienta, obsługiwane są synchroniczne JS wywołania międzyoperacji.

Serializacja obiektów

Platforma Blazor używa obiektu System.Text.Json do serializacji z następującymi wymaganiami i zachowaniami domyślnymi:

  • Typy muszą mieć konstruktor domyślny, metody dostępu get/set muszą być publiczne, a pola nigdy nie są serializowane.
  • Globalna domyślna serializacja nie jest dostosowywalna, aby uniknąć przerywania istniejących bibliotek składników, wpływu na wydajność i bezpieczeństwo oraz zmniejszeń niezawodności.
  • Serializowanie nazw elementów członkowskich platformy .NET powoduje, że nazwy kluczy JSON są małe.
  • Kod JSON jest deserializowany jako JsonElement wystąpienia języka C#, które zezwalają na mieszaną wielkość liter. Wewnętrzne rzutowanie do przypisania do właściwości modelu języka C# działa zgodnie z oczekiwaniami pomimo różnic przypadków między nazwami kluczy JSON i nazwami właściwości języka C#.
  • Złożone typy struktur, takie jak KeyValuePair, mogą zostać przycięte przez program IL Trimmer podczas publikowania i nie są obecne dla JS międzyoperamentu. Zalecamy utworzenie typów niestandardowych dla typów, które trymer IL przycina.
  • Blazorzawsze opiera się na odbiciu serializacji JSON, w tym w przypadku używania generowania źródła języka C#. Ustawienie JsonSerializerIsReflectionEnabledByDefault na wartość w false pliku projektu aplikacji powoduje błąd podczas próby serializacji.

Interfejs API JsonConverter jest dostępny na potrzeby serializacji niestandardowej. Właściwości można oznaczyć adnotacją za pomocą atrybutu [JsonConverter], aby zastąpić domyślną serializację dla istniejącego typu danych.

Aby uzyskać więcej informacji, zobacz następujące zasoby w dokumentacji platformy .NET:

Platforma Blazor obsługuje zoptymalizowane współdziałanie języka JS na tablicy bajtów, które unika kodowania/dekodowania tablic bajtów w schemacie Base64. Aplikacja może stosować serializację niestandardową i przekazywać bajty wynikowe. Aby uzyskać więcej informacji, zobacz Wywoływanie funkcji języka JavaScript z metod platformy .NET na platformie ASP.NET Core Blazor.

Platforma Blazor obsługuje współdziałanie języka JS, dla którego przeprowadzono unmarshaling, gdy duża liczba obiektów platformy .NET jest szybko serializowana lub gdy należy serializować duże obiekty platformy .NET albo wiele obiektów platformy .NET. Aby uzyskać więcej informacji, zobacz Wywoływanie funkcji języka JavaScript z metod platformy .NET na platformie ASP.NET Core Blazor.

Zadania oczyszczania modelu DOM podczas usuwania składników

Nie wykonuj JS kodu międzyoperajowego dla zadań oczyszczania MODELU DOM podczas usuwania składników. Zamiast tego użyj MutationObserver wzorca w języku JavaScript (JS) na kliencie z następujących powodów:

  • Składnik mógł zostać usunięty z modelu DOM przez czas wykonywania kodu oczyszczania w pliku Dispose{Async}.
  • Podczas renderowania Blazor po stronie serwera program renderujący mógł zostać usunięty przez strukturę przez czas wykonywania kodu oczyszczania w programie Dispose{Async}.

Wzorzec MutationObserver umożliwia uruchamianie funkcji po usunięciu elementu z modelu DOM.

W poniższym przykładzie DOMCleanup składnik:

  • Zawiera element <div> z wartością cleanupDivid . Element <div> zostanie usunięty z modelu DOM wraz z rest znacznikiem DOM składnika, gdy składnik zostanie usunięty z modelu DOM.
  • Ładuje klasę DOMCleanupJS z DOMCleanup.razor.js pliku i wywołuje jego createObserver funkcję w celu skonfigurowania wywołania zwrotnego MutationObserver . Te zadania są wykonywane w metodzie OnAfterRenderAsynccyklu życia.

DOMCleanup.razor:

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

<h1>DOM Cleanup Example</h1>

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

@code {
    private IJSObjectReference? module;

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

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

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

W poprzednim przykładzie JSDisconnectedException jest uwięziony podczas usuwania modułu w przypadku Blazorutraty obwodu SignalR . Jeśli poprzedni kod jest używany w Blazor WebAssembly aplikacji, nie ma SignalR połączenia do utraty, więc możesz usunąćcatch try-blok i pozostawić wiersz, który usuwa moduł ().await module.DisposeAsync(); Aby uzyskać więcej informacji, zobacz ASP.NET Core Blazor JavaScript interoperability (JS interop).

W poniższym przykładzie wywołanie zwrotne jest wykonywane za każdym razem, MutationObserver gdy nastąpi zmiana MODELU DOM. Wykonaj kod oczyszczania, gdy if instrukcja potwierdza, że element docelowy (cleanupDiv) został usunięty (if (targetRemoved) { ... }). Ważne jest rozłączenie i usunięcie MutationObserver elementu , aby uniknąć przecieku pamięci po wykonaniu kodu oczyszczania.

DOMCleanup.razor.js umieszczony obok poprzedniego DOMCleanup składnika:

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;

Wywołania międzyoperacyjne języka JavaScript bez obwodu

Ta sekcja dotyczy tylko aplikacji po stronie serwera.

Wywołania międzyoperacyjne języka JavaScript (JS) nie mogą być wystawiane po Blazorrozłączeniu obwodu SignalR . Bez obwodu podczas usuwania składników lub w dowolnym innym czasie, że obwód nie istnieje, następująca metoda wywołuje niepowodzenie i rejestruje komunikat, że obwód jest odłączony jako JSDisconnectedException:

Aby uniknąć rejestrowania lub rejestrowania JSDisconnectedException informacji niestandardowych, przechwyć wyjątek w instrukcji try-catch .

W poniższym przykładzie usuwania składników:

  • Składnik po stronie serwera implementuje IAsyncDisposableelement .
  • module jest elementem IJSObjectReference dla modułu JS .
  • JSDisconnectedException jest złapany i nie jest rejestrowany.
  • Opcjonalnie możesz rejestrować informacje niestandardowe w instrukcji catch na każdym preferowanym poziomie dziennika. Poniższy przykład nie rejestruje informacji niestandardowych, ponieważ zakłada, że deweloper nie dba o to, kiedy lub gdzie obwody są rozłączane podczas usuwania składników.
async ValueTask IAsyncDisposable.DisposeAsync()
{
    try
    {
        if (module is not null)
        {
            await module.DisposeAsync();
        }
    }
    catch (JSDisconnectedException)
    {
    }
}

Jeśli musisz wyczyścić własne JS obiekty lub wykonać inny JS kod na kliencie po utracie obwodu w aplikacji po stronie Blazor serwera, użyj MutationObserver wzorca JS w kliencie. Wzorzec MutationObserver umożliwia uruchamianie funkcji po usunięciu elementu z modelu DOM.

Aby uzyskać więcej informacji, zobacz następujące artykuły:

Buforowane pliki JavaScript

Pliki JavaScript (JS) i inne zasoby statyczne nie są zwykle buforowane na klientach podczas programowania w środowisku Development. Podczas programowania statyczne żądania zasobów zawierają nagłówek Cache-Control z wartością no-cache, max-age lub zero (0).

Podczas produkcji w środowisku Production pliki JS są zwykle buforowane przez klientów.

Aby wyłączyć buforowanie po stronie klienta w przeglądarkach, deweloperzy zwykle stosują jedną z następujących metod:

  • Wyłącz buforowanie, gdy konsola narzędzi deweloperskich przeglądarki jest otwarta. Wskazówki można znaleźć w dokumentacji narzędzi deweloperskich każdego osoby odpowiedzialnej za przeglądarkę:
  • Wykonaj ręczne odświeżanie przeglądarki dowolnej strony internetowej aplikacji platformy Blazor w celu ponownego załadowania plików JS z serwera. Oprogramowanie pośredniczące HTTP platformy ASP.NET Core zawsze honoruje prawidłowy nagłówek Cache-Control no-cache wysyłany przez klienta.

Aby uzyskać więcej informacji, zobacz:

Limity rozmiaru wywołań międzyoperacyjności języka JavaScript

Ta sekcja dotyczy tylko składników interaktywnych w aplikacjach po stronie serwera. W przypadku składników po stronie klienta struktura nie nakłada limitu rozmiaru danych wejściowych i wyjściowych międzyoperacyjności języka JavaScript (JS).

W przypadku składników interaktywnych w aplikacjach JS po stronie serwera międzyoperacyjne wywołania przekazywania danych z klienta do serwera są ograniczone do maksymalnego rozmiaru komunikatów przychodzących SignalR dozwolonych dla metod centrum, które są wymuszane ( HubOptions.MaximumReceiveMessageSize domyślnie: 32 KB). JS do komunikatów platformy .NET SignalR większych niż MaximumReceiveMessageSize zgłasza błąd. Struktura nie nakłada limitu rozmiaru komunikatu SignalR z centrum na klienta. Aby uzyskać więcej informacji na temat limitu rozmiaru, komunikatów o błędach i wskazówek dotyczących obsługi limitów rozmiaru komunikatów, zobacz wskazówki dotyczące ASP.NET CoreBlazorSignalR.

Określanie, gdzie aplikacja jest uruchomiona

Jeśli aplikacja ma znaczenie, aby wiedzieć, gdzie działa kod na potrzeby JS wywołań międzyoperamentowych, użyj polecenia OperatingSystem.IsBrowser , aby określić, czy składnik jest wykonywany w kontekście przeglądarki w zestawie WebAssembly.