unduhan file ASP.NET Core Blazor
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 8 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.
Artikel ini menjelaskan cara mengunduh file di Blazor aplikasi.
Unduhan file
Artikel ini membahas pendekatan untuk skenario berikut, di mana file tidak boleh dibuka oleh browser tetapi diunduh dan disimpan di klien:
- Streaming konten file ke buffer data biner mentah pada klien: Biasanya, pendekatan ini digunakan untuk file yang relatif kecil (< 250 MB).
- Unduh file melalui URL tanpa streaming: Biasanya, pendekatan ini digunakan untuk file yang relatif besar (> 250 MB).
Saat mengunduh file dari asal yang berbeda dari aplikasi, pertimbangan Cross-Origin Resource Sharing (CORS) berlaku. Untuk informasi selengkapnya, lihat bagian Berbagi Sumber Daya Lintas Asal (CORS).
Pertimbangan keamanan
Berhati-hatilah saat memberi pengguna kemampuan untuk mengunduh file dari server. Serangan cyber dapat mengeksekusi serangan Denial of Service (DoS), serangan eksploitasi API, atau mencoba membahayakan jaringan dan server dengan cara lain.
Langkah-langkah keamanan yang mengurangi kemungkinan serangan yang berhasil adalah:
- Unduh file dari area unduhan file khusus di server, sebaiknya dari drive non-sistem. Menggunakan lokasi khusus memudahkan untuk memberlakukan pembatasan keamanan pada file yang dapat diunduh. Nonaktifkan izin eksekusi pada area unduhan file.
- Pemeriksaan keamanan sisi klien mudah dilumpuhkan oleh pengguna berbahaya. Selalu lakukan pemeriksaan keamanan sisi klien di server juga.
- Jangan menerima file dari pengguna atau sumber lain yang tidak tepercaya lalu membuat file tersedia untuk diunduh segera tanpa melakukan pemeriksaan keamanan pada file. Untuk informasi selengkapnya, lihat Mengunggah file di ASP.NET Core.
Mengunduh dari aliran
Bagian ini berlaku untuk file yang biasanya berukuran hingga 250 MB.
Pendekatan yang direkomendasikan untuk mengunduh file yang relatif kecil (<250 MB) adalah mengalirkan konten file ke buffer data biner mentah pada klien dengan interop JavaScript (JS). Pendekatan ini efektif untuk komponen yang mengadopsi mode render interaktif tetapi bukan komponen yang mengadopsi penyajian sisi server statis (SSR statis).
Pendekatan yang direkomendasikan untuk mengunduh file yang relatif kecil (<250 MB) adalah mengalirkan konten file ke buffer data biner mentah pada klien dengan interop JavaScript (JS).
Peringatan
Pendekatan di bagian ini membaca konten file menjadi JS ArrayBuffer
. Pendekatan ini memuat seluruh file ke dalam memori klien, yang dapat mengganggu performa. Untuk mengunduh file yang relatif besar (>= 250 MB), sebaiknya ikuti panduan di bagian Unduh dari URL .
Fungsi berikut downloadFileFromStream
JS :
- Membaca aliran yang disediakan ke dalam
ArrayBuffer
. - Membuat untuk membungkus
Blob
ArrayBuffer
. - Membuat URL objek untuk berfungsi sebagai alamat unduhan file.
HTMLAnchorElement
Membuat (<a>
elemen).- Menetapkan nama file (
fileName
) dan URL (url
) untuk unduhan. - Memicu unduhan dengan menembakkan
click
peristiwa pada elemen jangkar. - Menghapus elemen jangkar.
- Mencabut URL objek (
url
) dengan memanggilURL.revokeObjectURL
. Ini adalah langkah penting untuk memastikan memori tidak bocor pada klien.
<script>
window.downloadFileFromStream = async (fileName, contentStreamReference) => {
const arrayBuffer = await contentStreamReference.arrayBuffer();
const blob = new Blob([arrayBuffer]);
const url = URL.createObjectURL(blob);
const anchorElement = document.createElement('a');
anchorElement.href = url;
anchorElement.download = fileName ?? '';
anchorElement.click();
anchorElement.remove();
URL.revokeObjectURL(url);
}
</script>
Catatan
Untuk panduan umum tentang JS lokasi dan rekomendasi kami untuk aplikasi produksi, lihat Lokasi JavaScript di aplikasi ASP.NET CoreBlazor.
Komponen berikut:
- Menggunakan interop byte-streaming asli untuk memastikan transfer file yang efisien ke klien.
- Memiliki metode bernama
GetFileStream
untuk mengambil Stream file yang diunduh ke klien. Pendekatan alternatif termasuk mengambil file dari penyimpanan atau menghasilkan file secara dinamis dalam kode C#. Untuk demonstrasi ini, aplikasi membuat file 50 KB data acak dari array byte baru (new byte[]
). Byte dibungkus dengan MemoryStream untuk berfungsi sebagai contoh file biner yang dihasilkan secara dinamis. - Metode:
DownloadFileFromStream
- Mengambil Stream dari
GetFileStream
. - Menentukan nama file ketika file disimpan di komputer pengguna. Contoh berikut menamai file
quote.txt
. - Membungkus Stream dalam DotNetStreamReference, yang memungkinkan streaming data file ke klien.
downloadFileFromStream
JS Memanggil fungsi untuk menerima data pada klien.
- Mengambil Stream dari
FileDownload1.razor
:
@page "/file-download-1"
@using System.IO
@inject IJSRuntime JS
<PageTitle>File Download 1</PageTitle>
<h1>File Download Example 1</h1>
<button @onclick="DownloadFileFromStream">
Download File From Stream
</button>
@code {
private Stream GetFileStream()
{
var randomBinaryData = new byte[50 * 1024];
var fileStream = new MemoryStream(randomBinaryData);
return fileStream;
}
private async Task DownloadFileFromStream()
{
var fileStream = GetFileStream();
var fileName = "log.bin";
using var streamRef = new DotNetStreamReference(stream: fileStream);
await JS.InvokeVoidAsync("downloadFileFromStream", fileName, streamRef);
}
}
@page "/file-download-1"
@using System.IO
@inject IJSRuntime JS
<PageTitle>File Download 1</PageTitle>
<h1>File Download Example 1</h1>
<button @onclick="DownloadFileFromStream">
Download File From Stream
</button>
@code {
private Stream GetFileStream()
{
var randomBinaryData = new byte[50 * 1024];
var fileStream = new MemoryStream(randomBinaryData);
return fileStream;
}
private async Task DownloadFileFromStream()
{
var fileStream = GetFileStream();
var fileName = "log.bin";
using var streamRef = new DotNetStreamReference(stream: fileStream);
await JS.InvokeVoidAsync("downloadFileFromStream", fileName, streamRef);
}
}
@page "/file-download-1"
@using System.IO
@inject IJSRuntime JS
<h1>File Download Example</h1>
<button @onclick="DownloadFileFromStream">
Download File From Stream
</button>
@code {
private Stream GetFileStream()
{
var randomBinaryData = new byte[50 * 1024];
var fileStream = new MemoryStream(randomBinaryData);
return fileStream;
}
private async Task DownloadFileFromStream()
{
var fileStream = GetFileStream();
var fileName = "log.bin";
using var streamRef = new DotNetStreamReference(stream: fileStream);
await JS.InvokeVoidAsync("downloadFileFromStream", fileName, streamRef);
}
}
@page "/file-download-1"
@using System.IO
@inject IJSRuntime JS
<h1>File Download Example</h1>
<button @onclick="DownloadFileFromStream">
Download File From Stream
</button>
@code {
private Stream GetFileStream()
{
var randomBinaryData = new byte[50 * 1024];
var fileStream = new MemoryStream(randomBinaryData);
return fileStream;
}
private async Task DownloadFileFromStream()
{
var fileStream = GetFileStream();
var fileName = "log.bin";
using var streamRef = new DotNetStreamReference(stream: fileStream);
await JS.InvokeVoidAsync("downloadFileFromStream", fileName, streamRef);
}
}
Untuk komponen di aplikasi sisi server yang harus mengembalikan Stream untuk file fisik, komponen dapat memanggil File.OpenRead, seperti yang ditunjukkan contoh berikut:
private Stream GetFileStream() => File.OpenRead(@"{PATH}");
Dalam contoh sebelumnya, {PATH}
tempat penampung adalah jalur ke file. @
Awalan menunjukkan bahwa string adalah string verbatim literal, yang memungkinkan penggunaan garis miring terbalik (\
) di jalur OS Windows dan tanda kutip ganda tertanam (""
) untuk satu kutipan di jalur. Atau, hindari string literal (@
) dan gunakan salah satu pendekatan berikut:
- Gunakan garis miring terbelakang yang diloloskan (
\\
) dan tanda kutip (\"
). - Gunakan garis miring maju (
/
) di jalur, yang didukung di seluruh platform di aplikasi ASP.NET Core, dan tanda kutip yang lolos (\"
).
Unduh dari URL
Bagian ini berlaku untuk file yang relatif besar, biasanya 250 MB atau lebih besar.
Pendekatan yang disarankan untuk mengunduh file yang relatif besar (>= 250 MB) dengan komponen atau file yang dirender secara interaktif dengan ukuran apa pun untuk komponen yang dirender secara statis adalah menggunakan JS untuk memicu elemen jangkar dengan nama dan URL file.
Pendekatan yang direkomendasikan untuk mengunduh file yang relatif besar (>= 250 MB) adalah dengan menggunakan JS untuk memicu elemen jangkar dengan nama dan URL file.
Contoh di bagian ini menggunakan file unduhan bernama quote.txt
, yang ditempatkan dalam folder bernama files
di akar web aplikasi (wwwroot
folder). Penggunaan files
folder hanya untuk tujuan demonstrasi. Anda dapat mengatur file yang dapat diunduh dalam tata letak folder apa pun dalam akar web (wwwroot
folder) yang Anda inginkan, termasuk menyajikan file langsung dari wwwroot
folder.
wwwroot/files/quote.txt
:
When victory is ours, we'll wipe every trace of the Thals and their city from the face of this land. We will avenge the deaths of all Kaleds who've fallen in the cause of right and justice and build a peace which will be a monument to their sacrifice. Our battle cry will be "Total extermination of the Thals!"
- General Ravon (Guy Siner, http://guysiner.com/)
Dr. Who: Genesis of the Daleks (https://www.bbc.co.uk/programmes/p00vd5g2)
Copyright 1975 BBC (https://www.bbc.co.uk/)
When victory is ours, we'll wipe every trace of the Thals and their city from the face of this land. We will avenge the deaths of all Kaleds who've fallen in the cause of right and justice and build a peace which will be a monument to their sacrifice. Our battle cry will be "Total extermination of the Thals!"
- General Ravon (Guy Siner, http://guysiner.com/)
Dr. Who: Genesis of the Daleks (https://www.bbc.co.uk/programmes/p00vd5g2)
Copyright 1975 BBC (https://www.bbc.co.uk/)
When victory is ours, we'll wipe every trace of the Thals and their city from the face of this land. We will avenge the deaths of all Kaleds who've fallen in the cause of right and justice and build a peace which will be a monument to their sacrifice. Our battle cry will be "Total extermination of the Thals!"
- General Ravon (Guy Siner, http://guysiner.com/)
Dr. Who: Genesis of the Daleks (https://www.bbc.co.uk/programmes/p00vd5g2)
Copyright 1975 BBC (https://www.bbc.co.uk/)
When victory is ours, we'll wipe every trace of the Thals and their city from the face of this land. We will avenge the deaths of all Kaleds who've fallen in the cause of right and justice and build a peace which will be a monument to their sacrifice. Our battle cry will be "Total extermination of the Thals!"
- General Ravon (Guy Siner, http://guysiner.com/)
Dr. Who: Genesis of the Daleks (https://www.bbc.co.uk/programmes/p00vd5g2)
Copyright 1975 BBC (https://www.bbc.co.uk/)
Fungsi berikut triggerFileDownload
JS :
HTMLAnchorElement
Membuat (<a>
elemen).- Menetapkan nama file (
fileName
) dan URL (url
) untuk unduhan. - Memicu unduhan dengan menembakkan
click
peristiwa pada elemen jangkar. - Menghapus elemen jangkar.
<script>
window.triggerFileDownload = (fileName, url) => {
const anchorElement = document.createElement('a');
anchorElement.href = url;
anchorElement.download = fileName ?? '';
anchorElement.click();
anchorElement.remove();
}
</script>
Catatan
Untuk panduan umum tentang JS lokasi dan rekomendasi kami untuk aplikasi produksi, lihat Lokasi JavaScript di aplikasi ASP.NET CoreBlazor.
Contoh komponen berikut mengunduh file dari asal yang sama dengan yang digunakan aplikasi. Jika unduhan file dicoba dari asal yang berbeda, konfigurasikan Berbagi Sumber Daya Lintas Asal (CORS). Untuk informasi selengkapnya, lihat bagian Berbagi Sumber Daya Lintas Asal (CORS).
FileDownload2.razor
:
@page "/file-download-2"
@inject IJSRuntime JS
<PageTitle>File Download 2</PageTitle>
<h1>File Download Example 2</h1>
<button @onclick="DownloadFileFromURL">
Download File From URL
</button>
@code {
private async Task DownloadFileFromURL()
{
var fileName = "quote.txt";
var fileURL = "/files/quote.txt";
await JS.InvokeVoidAsync("triggerFileDownload", fileName, fileURL);
}
}
Untuk komponen interaktif, tombol dalam contoh sebelumnya memanggil DownloadFileFromURL
handler untuk memanggil fungsi triggerFileDownload
JavaScript (JS).
Jika komponen mengadopsi penyajian sisi server statis (SSR statis), tambahkan penanganan aktivitas untuk tombol (addEventListener
(dokumentasi MDN)) untuk memanggil triggerFileDownload
mengikuti panduan di ASP.NET Core Blazor JavaScript dengan penyajian sisi server statis (SSR statis).
@page "/file-download-2"
@inject IJSRuntime JS
<PageTitle>File Download 2</PageTitle>
<h1>File Download Example 2</h1>
<button @onclick="DownloadFileFromURL">
Download File From URL
</button>
@code {
private async Task DownloadFileFromURL()
{
var fileName = "quote.txt";
var fileURL = "/files/quote.txt";
await JS.InvokeVoidAsync("triggerFileDownload", fileName, fileURL);
}
}
Untuk komponen interaktif, tombol dalam contoh sebelumnya memanggil DownloadFileFromURL
handler untuk memanggil fungsi triggerFileDownload
JavaScript (JS).
Jika komponen mengadopsi penyajian sisi server statis (SSR statis), tambahkan penanganan aktivitas untuk tombol (addEventListener
(dokumentasi MDN)) untuk memanggil triggerFileDownload
mengikuti panduan di ASP.NET Core Blazor JavaScript dengan penyajian sisi server statis (SSR statis).
@page "/file-download-2"
@inject IJSRuntime JS
<h1>File Download Example 2</h1>
<button @onclick="DownloadFileFromURL">
Download File From URL
</button>
@code {
private async Task DownloadFileFromURL()
{
var fileName = "quote.txt";
var fileURL = "https://localhost:5001/files/quote.txt";
await JS.InvokeVoidAsync("triggerFileDownload", fileName, fileURL);
}
}
Ubah port dalam contoh sebelumnya agar sesuai dengan port pengembangan localhost lingkungan Anda.
@page "/file-download-2"
@inject IJSRuntime JS
<h1>File Download Example 2</h1>
<button @onclick="DownloadFileFromURL">
Download File From URL
</button>
@code {
private async Task DownloadFileFromURL()
{
var fileName = "quote.txt";
var fileURL = "https://localhost:5001/files/quote.txt";
await JS.InvokeVoidAsync("triggerFileDownload", fileName, fileURL);
}
}
Ubah port dalam contoh sebelumnya agar sesuai dengan port pengembangan localhost lingkungan Anda.
Berbagi Sumber Daya Lintas Asal (CORS)
Tanpa mengambil langkah-langkah lebih lanjut untuk mengaktifkan Cross-Origin Resource Sharing (CORS) untuk file yang tidak memiliki asal yang sama dengan aplikasi, mengunduh file tidak akan melewati pemeriksaan CORS yang dibuat oleh browser.
Untuk informasi selengkapnya tentang CORS dengan aplikasi ASP.NET Core dan produk dan layanan Microsoft lainnya yang menghosting file untuk diunduh, lihat sumber daya berikut:
- Mengaktifkan Permintaan Lintas-Asal (CORS) di ASP.NET Core 1.0
- Menggunakan Azure CDN dengan CORS (dokumentasi Azure)
- Dukungan Cross-Origin Resource Sharing (CORS) untuk Azure Storage (REST dokumentasi)
- Core Cloud Services - Menyiapkan CORS untuk situs web dan aset penyimpanan Anda (modul Learn)
- Referensi Konfigurasi modul IIS CORS (dokumentasi IIS)
Sumber Daya Tambahan:
- file statis ASP.NET Core Blazor
- Blazor ASP.NET interoperabilitas Core JavaScript (JS interop)
- Lokasi JavaScript di aplikasi ASP.NET Core Blazor
- ASP.NET Core Blazor JavaScript dengan penyajian sisi server statis (SSR statis)
<a>
: Elemen Jangkar: Keamanan dan privacy (dokumentasi MDN)- unggahan file ASP.NET Core Blazor
- Blazorsampel repositori GitHub () (
dotnet/blazor-samples
cara mengunduh)
ASP.NET Core