Bagikan melalui


unduhan file ASP.NET Core Blazor

Catatan

Ini bukan versi terbaru dari artikel ini. Untuk rilis saat ini, lihat versi .NET 8 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 8 dari artikel ini.

Artikel ini menjelaskan cara mengunduh file di Blazor aplikasi.

Unduhan file

File dapat diunduh dari aset statis aplikasi sendiri atau dari lokasi lain:

  • aplikasi ASP.NET Core menggunakan Middleware Aset Statis Peta atau Middleware File Statis untuk melayani file kepada klien aplikasi sisi server. Untuk informasi lebih lanjut, lihat file statis Blazor ASP.NET Core.
  • Panduan dalam artikel ini juga berlaku untuk jenis server file lain yang tidak menggunakan .NET, seperti Content Delivery Networks (CDN).
  • ASP.NET Core menggunakan File Middleware Statis untuk melayani file kepada klien aplikasi sisi server.
  • Panduan dalam artikel ini juga berlaku untuk jenis server file lain yang tidak menggunakan .NET, seperti Content Delivery Networks (CDN).

Artikel ini membahas pendekatan untuk skenario berikut, di mana file tidak boleh dibuka oleh browser tetapi diunduh dan disimpan di klien:

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 downloadFileFromStreamJS :

  • 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 memanggil URL.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.
    • downloadFileFromStreamJS Memanggil fungsi untuk menerima data pada klien.

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

<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/)

Fungsi berikut triggerFileDownloadJS :

  • 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 triggerFileDownloadJavaScript (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:

Sumber Daya Tambahan: