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.
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:
- Wywoływanie funkcji języka JavaScript z metod platformy .NET na platformie ASP.NET Core Blazor
- Wywoływanie metod platformy .NET z funkcji języka JavaScript z na platformie ASP.NET Core Blazor
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 Blazor po stronie serwera ASP.NET Core).
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:
- TypeScript
- Samouczek: tworzenie aplikacji ASP.NET Core za pomocą języka TypeScript w programie Visual Studio
- Zarządzanie pakietami npm w programie Visual Studio
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ą addEventListener
metody , 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ąćtry
-catch
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:
- Lokalizacja języka JavaScript w aplikacjach ASP.NET Core Blazor
- Wprowadzenie do zdarzeń (dokumentacja MDN)
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.
Aby uzyskać więcej informacji, zobacz następujące artykuły:
Aby uzyskać więcej informacji, zobacz Wywoływanie funkcji języka JavaScript z metod platformy .NET na platformie ASP.NET Core Blazor.
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ść wfalse
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:
- Serializacja i deserializacja JSON (marshalling i unmarshalling) na platformie .NET
-
Jak dostosować nazwy i wartości właściwości przy użyciu obiektu
System.Text.Json
- Jak pisać niestandardowe konwertery na potrzeby serializacji JSON (marshalling) na platformie .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ąid
cleanupDiv
. 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ę
DOMCleanup
JS zDOMCleanup.razor.js
pliku i wywołuje jegocreateObserver
funkcję w celu skonfigurowania wywołania zwrotnegoMutationObserver
. Te zadania są wykonywane w metodzieOnAfterRenderAsync
cyklu ż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ąćtry
-catch
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;
Powyższe podejścia dołączają MutationObserver
do target.parentNode
, co działa do momentu usunięcia samego parentNode
z struktury DOM. Jest to typowy scenariusz, na przykład podczas przechodzenia do nowej strony, co powoduje usunięcie całego składnika strony z modelu DOM. W takich przypadkach wszystkie składniki podrzędne obserwujące zmiany na stronie nie są prawidłowo czyszczone.
Nie zakładaj, że obserwowanie document.body
, zamiast target.parentNode
, jest lepszym celem. Obserwowanie document.body
ma implikacje wydajnościowe, ponieważ logika funkcji wywoławczej jest wykonywana dla wszystkich aktualizacji DOM, niezależnie od tego, czy mają coś wspólnego z twoim elementem. Użyj jednej z następujących metod:
- W przypadkach, w których można zidentyfikować odpowiedni węzeł przodka do obserwowania, użyj z nim
MutationObserver
. Najlepiej, aby ten nadrzędny element był skierowany na zmiany, które mają być obserwowane, a nie nadocument.body
. - Zamiast używać
MutationObserver
, rozważ użycie elementu niestandardowego idisconnectedCallback
. Zdarzenie jest zawsze wywoływane, gdy element niestandardowy jest odłączony, niezależnie od tego, gdzie znajduje się w DOM względem zmiany w DOM.
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:
- JS wywołania metody międzyoperacyjnej
-
Dispose
/DisposeAsync
wywołuje każdą IJSObjectReferencemetodę .
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.