Catatan
Akses ke halaman ini memerlukan otorisasi. Anda dapat mencoba masuk atau mengubah direktori.
Akses ke halaman ini memerlukan otorisasi. Anda dapat mencoba mengubah direktori.
Catatan
Ini bukan versi terbaru dari artikel ini. Untuk rilis saat ini, lihat versi .NET 9 dari artikel ini.
Peringatan
Versi ASP.NET Core ini tidak lagi didukung. Untuk informasi selengkapnya, lihat Kebijakan Dukungan .NET dan .NET Core. Untuk rilis saat ini, lihat versi .NET 9 dari artikel ini.
Penting
Informasi ini berkaitan dengan produk pra-rilis yang mungkin dimodifikasi secara substansial sebelum dirilis secara komersial. Microsoft tidak memberikan jaminan, tersirat maupun tersurat, sehubungan dengan informasi yang diberikan di sini.
Untuk rilis saat ini, lihat versi .NET 9 dari artikel ini.
Aplikasi Blazor dapat menjalankan fungsi JavaScript (JS) dari metode .NET dan metode .NET dari fungsi JS. Skenario ini disebut interoperabilitas JavaScript (interop JS).
Panduan interop JS lebih lanjut disediakan dalam artikel berikut:
- Memanggil fungsi JavaScript dari metode .NET di Blazor ASP.NET Core
- Memanggil metode .NET dari fungsi JavaScript di Blazor ASP.NET Core
- Blazor
Catatan
API interop JavaScript [JSImport]
/[JSExport]
tersedia untuk komponen sisi klien di ASP.NET Core di .NET 7 atau yang lebih baru.
Untuk informasi lebih lanjut, lihat Interoperabilitas JavaScript JSImport/JSExport dengan ASP.NET Core Blazor.
Pemadatan untuk komponen server interaktif dengan data yang tidak tepercaya
Dengan kompresi, yang diaktifkan secara default, hindari membuat komponen sisi server interaktif yang aman (diautentikasi/diotorisasi) yang merender data dari sumber yang tidak tepercaya. Sumber yang tidak tepercaya termasuk parameter rute, string kueri, data dari JS interop, dan sumber data lain yang dapat dikontrol pengguna pihak ketiga (database, layanan eksternal). Untuk informasi selengkapnya, lihat Blazor dan panduan mitigasi ancaman untuk SignalR rendering sisi server interaktif ASP.NET Core.
Paket abstraksi dan fitur interop JavaScript
Paket @microsoft/dotnet-js-interop
(npmjs.com
) (Microsoft.JSInterop
paket NuGet) menyediakan abstraksi dan fitur untuk interop antara kode .NET dan JavaScript (JS). Sumber referensi tersedia di dotnet/aspnetcore
repositori GitHub (/src/JSInterop
folder). Untuk informasi selengkapnya, lihat file repositori README.md
GitHub.
Catatan
Tautan dokumentasi ke sumber referensi .NET biasanya memuat cabang default repositori, yang mewakili pengembangan saat ini untuk rilis .NET berikutnya. Untuk memilih tag untuk rilis tertentu, gunakan menu dropdown Beralih cabang atau tag. Untuk informasi lebih lanjut, lihat Cara memilih tag versi kode sumber ASP.NET Core (dotnet/AspNetCore.Docs #26205).
Sumber daya tambahan untuk menulis JS skrip interop di TypeScript:
- TypeScript
- Tutorial: Membuat aplikasi ASP.NET Core dengan TypeScript di Visual Studio
- Mengelola paket npm di Visual Studio
Interaksi dengan DOM
Hanya bermutasi DOM dengan JavaScript (JS) saat objek tidak berinteraksi dengan Blazor. Blazor mempertahankan representasi DOM dan berinteraksi langsung dengan objek DOM. Jika elemen yang dirender oleh Blazor dimodifikasi secara eksternal menggunakan JS secara langsung atau melalui Interop JS, DOM mungkin tidak lagi cocok dengan representasi internal Blazor, yang dapat mengakibatkan perilaku yang tidak ditentukan. Perilaku yang tidak ditentukan mungkin hanya dapat mengganggu presentasi elemen atau fungsinya, tetapi juga dapat menimbulkan risiko keamanan ke aplikasi atau server.
Panduan ini tidak hanya berlaku untuk kode interop JS Anda sendiri, tetapi juga untuk setiap pustaka JS yang digunakan aplikasi, termasuk apa pun yang disediakan oleh kerangka kerja pihak ketiga, seperti Bootstrap JS dan jQuery.
Dalam beberapa contoh dokumentasi, JS interop digunakan untuk mengubah elemen semata-mata untuk tujuan demonstrasi sebagai bagian dari contoh. Dalam kasus tersebut, peringatan muncul di teks.
Untuk informasi lebih lanjut, lihat Memanggil fungsi JavaScript dari metode .NET di Blazor ASP.NET Core.
Kelas JavaScript dengan bidang bertipe fungsi
Kelas JavaScript dengan bidang fungsi jenis tidak didukung oleh BlazorJS interop. Gunakan fungsi Javascript di kelas.
Tidak didukung:GreetingHelpers.sayHello
di kelas berikut sebagai bidang fungsi jenis tidak ditemukan oleh Blazorinterop 's JS dan tidak dapat dijalankan dari kode C#:
export class GreetingHelpers {
sayHello = function() {
...
}
}
Didukung:GreetingHelpers.sayHello
di kelas berikut, fungsi ini didukung:
export class GreetingHelpers {
sayHello() {
...
}
}
Fungsi panah juga didukung:
export class GreetingHelpers {
sayHello = () => {
...
}
}
Hindari pengendali acara dalam baris
Fungsi JavaScript dapat dipanggil langsung dari penanganan aktivitas sebaris. Dalam contoh berikut, alertUser
adalah fungsi JavaScript yang dipanggil saat tombol dipilih oleh pengguna:
<button onclick="alertUser">Click Me!</button>
Namun, penggunaan penanganan aktivitas sebaris adalah pilihan desain yang buruk untuk memanggil fungsi JavaScript:
- Mencampur markup HTML dan kode JavaScript sering menyebabkan kode yang tidak dapat dikelola.
- Eksekusi penanganan aktivitas sebaris dapat diblokir oleh Kebijakan Keamanan Konten (CSP) (dokumentasi MDN).
Sebaiknya hindari penanganan acara sebaris dan memilih pendekatan yang menetapkan handler menggunakan JavaScript dengan addEventListener
, seperti yang ditunjukkan contoh berikut:
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)
{
}
}
}
}
Dalam contoh sebelumnya, JSDisconnectedException terjebak selama pembuangan modul jika sirkuit Blazor dari SignalR hilang. Jika kode sebelumnya digunakan dalam aplikasi Blazor WebAssembly, tidak ada koneksi yang perlu dilepaskan SignalR, sehingga Anda dapat menghapus blok try
-catch
dan meninggalkan baris yang membuang modul await module.DisposeAsync();
. Untuk informasi selengkapnya, lihat ASP.NET Blazor interoperabilitas Core JavaScript (JS interop).
Untuk informasi selengkapnya, lihat sumber daya berikut:
Panggilan JavaScript asinkron
JS panggilan interop bersifat asinkron, terlepas dari apakah kode yang dipanggil bersifat sinkron atau asinkron. Panggilan bersifat asinkron untuk memastikan bahwa komponen kompatibel di seluruh model penyajian sisi server dan sisi klien. Saat mengadopsi penyajian sisi server, JS panggilan interop harus asinkron karena dikirim melalui koneksi jaringan. Untuk aplikasi yang secara eksklusif mengadopsi rendering sisi klien, panggilan interop sinkron JS didukung.
Untuk informasi lebih lanjut, baca artikel berikut:
Untuk informasi lebih lanjut, lihat Memanggil fungsi JavaScript dari metode .NET di Blazor ASP.NET Core.
Serialisasi objek
Blazor menggunakan System.Text.Json untuk serialisasi dengan persyaratan dan perilaku default berikut:
- Jenis harus memiliki konstruktor default,
get
/set
pengakses harus publik, dan bidang tidak pernah diserialisasi. - Serialisasi default global tidak dapat disesuaikan untuk menghindari kerusakan pustaka komponen yang ada, berdampak pada performa dan keamanan, serta pengurangan keandalan.
- Serialisasi nama anggota .NET menghasilkan nama kunci JSON huruf kecil.
- JSON dideserialisasi sebagai JsonElement instans C#, yang mengizinkan casing campuran. Transformasi internal untuk penugasan ke properti model C# berfungsi sesuai harapan meskipun ada perbedaan kasus antara nama kunci JSON dan nama properti C#.
- Jenis kerangka kerja kompleks, seperti KeyValuePair, mungkin dipangkas oleh Pemangkas IL saat publikasi dan tidak ada untuk penggunaan interop JS atau serialisasi atau deserialisasi JSON. Kami merekomendasikan membuat tipe kustom untuk tipe yang dipangkas oleh IL Trimmer.
-
Blazor selalu bergantung pada refleksi JSON untuk serialisasi, termasuk saat menggunakan generasi sumber C# . Pengaturan
JsonSerializerIsReflectionEnabledByDefault
kefalse
dalam file proyek aplikasi menghasilkan kesalahan saat serialisasi dicoba.
API JsonConverter tersedia untuk serialisasi kustom. Properti dapat dianotasi dengan atribut [JsonConverter]
guna menggantikan serialisasi default untuk tipe data yang ada.
Untuk informasi lebih lanjut, lihat sumber daya berikut ini dalam dokumentasi .NET:
- Serialisasi dan deserialisasi JSON (marshalling dan unmarshalling) di .NET
-
Cara menyesuaikan nama dan nilai properti dengan
System.Text.Json
- Cara menulis konverter kustom untuk serialisasi JSON (marshalling) di .NET
Blazor mendukung interop JS array byte yang dioptimalkan yang menghindari pengodean/pendekodean array byte ke Base64. Aplikasi dapat menerapkan serialisasi kustom dan meneruskan byte yang dihasilkan. Untuk informasi lebih lanjut, lihat Memanggil fungsi JavaScript dari metode .NET di Blazor ASP.NET Core.
Blazor mendukung interop JS unmarshalled saat volume objek .NET yang tinggi diserialisasikan dengan cepat atau saat objek .NET besar atau saat banyak objek .NET harus diserialisasi. Untuk informasi lebih lanjut, lihat Memanggil fungsi JavaScript dari metode .NET di Blazor ASP.NET Core.
Langkah-langkah pembersihan DOM selama pembuangan komponen
Jangan jalankan JS kode interop untuk tugas pembersihan DOM selama pembuangan komponen. Sebagai gantinya MutationObserver
, gunakan pola di JavaScript (JS) pada klien karena alasan berikut:
- Komponen mungkin telah dihapus dari DOM pada saat kode pembersihan Anda dijalankan di
Dispose{Async}
. - Selama rendering sisi server, perender Blazor mungkin telah dibersihkan oleh kerangka kerja pada saat kode pembersihan Anda dijalankan di
Dispose{Async}
.
Pola ini MutationObserver
memungkinkan Anda menjalankan fungsi saat elemen dihapus dari DOM.
Dalam contoh berikut, komponen DOMCleanup
:
- Mengandung
<div>
denganid
daricleanupDiv
. Elemen<div>
dihapus dari DOM bersama dengan markup DOM komponen lainnya saat komponen dihapus dari DOM. - Memuat kelas
DOMCleanup
JS dari fileDOMCleanup.razor.js
dan memanggil fungsicreateObserver
nya untuk menyiapkan mekanismeMutationObserver
. Tugas-tugas ini dicapai dalamOnAfterRenderAsync
metode siklus hidup.
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)
{
}
}
}
}
Dalam contoh sebelumnya, JSDisconnectedException terjebak selama pembuangan modul jika sirkuit Blazor dari SignalR hilang. Jika kode sebelumnya digunakan dalam aplikasi Blazor WebAssembly, tidak ada koneksi yang perlu dilepaskan SignalR, sehingga Anda dapat menghapus blok try
-catch
dan meninggalkan baris yang membuang modul await module.DisposeAsync();
. Untuk informasi selengkapnya, lihat ASP.NET Blazor interoperabilitas Core JavaScript (JS interop).
Dalam contoh berikut, MutationObserver
panggilan balik dijalankan setiap kali perubahan DOM terjadi. Jalankan kode pembersihan Anda ketika pernyataan if
mengonfirmasi bahwa elemen target (cleanupDiv
) dihapus (if (targetRemoved) { ... }
). Penting untuk memutuskan sambungan dan menghapus MutationObserver
untuk menghindari kebocoran memori setelah kode pembersihan Anda selesai dijalankan.
DOMCleanup.razor.js
ditempatkan berdampingan DOMCleanup
dengan komponen sebelumnya:
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;
Pendekatan sebelumnya melampirkan MutationObserver
ke target.parentNode
, yang berfungsi sampai parentNode
itu sendiri dihapus dari DOM. Ini adalah skenario umum, misalnya, saat menavigasi ke halaman baru, yang menyebabkan seluruh komponen halaman dihapus dari DOM. Dalam kasus seperti itu, komponen anak apa pun yang mengamati perubahan di halaman tidak dibersihkan dengan benar.
Jangan berasumsi bahwa mengamati document.body
, daripada target.parentNode
, adalah target yang lebih baik. Mengamati document.body
memiliki dampak pada kinerja karena logika panggilan balik dijalankan untuk semua pembaruan DOM, terlepas dari apakah itu berhubungan dengan elemen Anda atau tidak. Gunakan salah satu pendekatan berikut:
- Jika Anda dapat mengidentifikasi simpul leluhur yang sesuai untuk diamati, gunakan
MutationObserver
dengannya. Idealnya, pendahulu ini dibatasi pada perubahan yang ingin Anda amati, daripadadocument.body
. - Alih-alih menggunakan
MutationObserver
, pertimbangkan untuk menggunakan elemen kustom dandisconnectedCallback
. Event selalu dipicu ketika elemen kustom Anda terputus, tidak peduli di mana posisinya di dalam DOM sehubungan dengan perubahan DOM.
Panggilan interoperabilitas JavaScript tanpa menggunakan rangkaian
Bagian ini hanya berlaku untuk aplikasi sisi server.
Panggilan interop JavaScript (JS) tidak dapat dikeluarkan setelah sirkuit Blazor milik SignalR terputus. Tanpa sirkuit selama pembuangan komponen atau pada waktu lain ketika sirkuit tidak ada, pemanggilan metode berikut gagal dan mencatat pesan bahwa sirkuit terputus sebagai JSDisconnectedException:
-
JS panggilan metode interop
- IJSRuntime.InvokeAsync
- JSRuntimeExtensions.InvokeAsync
- JSRuntimeExtensions.InvokeVoidAsync
InvokeNewAsync
GetValueAsync
SetValueAsync
-
Dispose
/DisposeAsync
memanggil setiap IJSObjectReference.
- JS panggilan metode interop
-
Dispose
/DisposeAsync
memanggil setiap IJSObjectReference.
Untuk menghindari pencatatan JSDisconnectedException atau mencatat informasi kustom, tangkap pengecualian dengan pernyataan try-catch
.
Untuk contoh pembuangan komponen berikut:
- Komponen sisi server mengimplementasikan IAsyncDisposable.
-
module
merupakan IJSObjectReference untuk modul JS. - JSDisconnectedException telah tertangkap dan tidak dicatat.
- Secara opsional, Anda dapat mencatat informasi kustom dalam pernyataan di
catch
tingkat log mana pun yang Anda sukai. Contoh berikut tidak mencatat informasi kustom karena mengasumsikan pengembang tidak peduli tentang kapan atau di mana sirkuit terputus selama pembuangan komponen.
async ValueTask IAsyncDisposable.DisposeAsync()
{
try
{
if (module is not null)
{
await module.DisposeAsync();
}
}
catch (JSDisconnectedException)
{
}
}
Jika Anda harus membersihkan objek Anda sendiri JS atau menjalankan kode lain JS pada klien setelah sirkuit hilang di aplikasi di sisi Blazor server, gunakan pola MutationObserver
di JS untuk klien. Pola ini MutationObserver
memungkinkan Anda menjalankan fungsi saat elemen dihapus dari DOM.
Untuk informasi lebih lanjut, baca artikel berikut:
- Blazor ASP.NET Core: Bagian JavaScript interop membahas penanganan kesalahan dalam berbagai skenario interoperabilitas.
- ASP.NET Core Razor pembuangan komponen: Artikel ini menjelaskan cara menerapkan pola pembuangan dalam komponen Razor.
File JavaScript yang di-cache
File JavaScript (JS) dan aset statis lainnya biasanya tidak disimpan dalam cache pada klien selama pengembangan di lingkungan Development
. Selama pengembangan, permintaan aset statis menyertakan header Cache-Control
dengan nilai no-cache
atau max-age
dengan nilai nol (0
).
Selama produksi di Production
lingkungan, file JS biasanya di-cache oleh klien.
Untuk menonaktifkan pencacahan sisi klien di browser, pengembang biasanya mengadopsi salah satu dari pendekatan berikut:
- Nonaktifkan cache ketika konsol alat pengembang pada browser terbuka. Panduan dapat ditemukan dalam dokumentasi alat pengembang dari setiap pemeliharaan browser:
- Lakukan refresh browser manual pada halaman web mana pun dari aplikasi Blazor untuk memuat ulang file JS dari server. Middleware HTTP Caching dari ASP.NET Core selalu menghormati header no-cache yang valid yang dikirim oleh klien.
Untuk informasi selengkapnya, lihat:
Batas ukuran pada panggilan interop JavaScript
Bagian ini hanya berlaku untuk komponen interaktif di aplikasi sisi server. Untuk komponen sisi klien, kerangka kerja tidak memberlakukan batasan pada ukuran input dan output interop JavaScript (JS).
Untuk komponen interaktif di aplikasi sisi server, JS panggilan interop yang meneruskan data dari klien ke server dibatasi oleh ukuran pesan masuk maksimum yang diizinkan untuk metode hub, dengan ukuran default 32 KB. Pesan .NET yang lebih besar dari JS akan memicu kesalahan. Kerangka kerja tidak memberlakukan batasan SignalR ukuran pesan dari hub ke klien. Untuk informasi selengkapnya tentang batas ukuran, pesan kesalahan, dan panduan tentang menangani batas ukuran pesan, lihat Blazor ASP.NET CoreSignalR.
Menentukan tempat aplikasi berjalan
Jika relevan bagi aplikasi untuk mengetahui di mana kode sedang berjalan untuk JS panggilan interop, gunakan OperatingSystem.IsBrowser untuk menentukan apakah komponen sedang berjalan di dalam konteks browser pada WebAssembly.
ASP.NET Core