download di file ASP.NET Core Blazor
Nota
Questa non è la versione più recente di questo articolo. Per la versione corrente, vedere la versione .NET 9 di questo articolo.
Avviso
Questa versione di ASP.NET Core non è più supportata. Per altre informazioni, vedere i criteri di supporto di .NET e .NET Core. Per la versione corrente, vedere la versione .NET 9 di questo articolo.
Importante
Queste informazioni si riferiscono a un prodotto non definitive che può essere modificato in modo sostanziale prima che venga rilasciato commercialmente. Microsoft non riconosce alcuna garanzia, espressa o implicita, in merito alle informazioni qui fornite.
Per la versione corrente, vedere la versione .NET 9 di questo articolo.
Questo articolo illustra come scaricare i file nelle Blazor app.
Download dei file
Questo articolo illustra gli approcci per gli scenari seguenti, in cui un file non deve essere aperto da un browser, ma scaricato e salvato nel client:
- Trasmettere il contenuto di file a un buffer di dati binari non elaborato nel client: in genere, questo approccio viene usato per file relativamente piccoli (< 250 MB).
- Scaricare un file tramite un URL senza streaming: in genere, questo approccio viene usato per file relativamente grandi (> 250 MB).
Quando si scaricano file da un'origine diversa da quella dell'app, si applicano considerazioni sulla condivisione di risorse tra le origini (CORS). Per ulteriori informazioni, consultare la sezione Condivisione risorse tra le origini (CORS).
Considerazioni relative alla sicurezza
Prestare attenzione quando si fornisce agli utenti la possibilità di scaricare file da un server. I cyberattacker possono eseguire attacchi Denial of Service (DoS), attacchi di sfruttamento delle API o tentare di compromettere reti e server in altri modi.
I passaggi di sicurezza che riducono la probabilità di un attacco riuscito sono:
- Scaricare i file da un'area di download di file dedicata nel server, preferibilmente da un'unità non di sistema. L'uso di un percorso dedicato semplifica l'imposizione di restrizioni di sicurezza per i file scaricabili. Disabilitare le autorizzazioni di esecuzione nell'area di download dei file.
- I controlli di sicurezza lato client sono facili da aggirare da parte di utenti malintenzionati. Eseguire sempre controlli di sicurezza sul lato client anche nel server.
- Non ricevere file da utenti o altre origini non attendibili e quindi rendere i file disponibili per il download immediato senza eseguire controlli di sicurezza sui file. Per altre informazioni, vedere Caricare file in ASP.NET Core.
Scaricare da uno streaming
Questa sezione si applica ai file con dimensioni massime di 250 MB.
L'approccio consigliato per il download di file relativamente piccoli (< 250 MB) consiste nel trasmettere il contenuto del file a un buffer di dati binari non elaborati nel client con JS JavaScript (). Questo approccio è efficace per i componenti che adottano una modalità di rendering interattiva, ma non i componenti che adottano il rendering statico lato server (SSR statico).
L'approccio consigliato per il download di file relativamente piccoli (< 250 MB) consiste nel trasmettere il contenuto del file a un buffer di dati binari non elaborati nel client con JS JavaScript ().
Avviso
L'approccio descritto in questa sezione legge il contenuto del file in un oggetto JS ArrayBuffer
. Questo approccio carica l'intero file nella memoria del client, che può compromettere le prestazioni. Per scaricare file relativamente grandi (>= 250 MB), è consigliabile seguire le indicazioni nella sezione Download from a URL (Scarica da un URL ).
La funzione seguente downloadFileFromStream
JS :
- Legge il flusso di dati fornito in un oggetto
ArrayBuffer
. - Crea un
Blob
per avvolgere ilArrayBuffer
. - Crea un URL dell'oggetto da usare come indirizzo di download del file.
- Crea un elemento
HTMLAnchorElement
(<a>
). - Assegna il nome del file (
fileName
) e l'URL (url
) per il download. - Attiva il download attivando un
click
evento sull'elemento di ancoraggio. - Rimuove l'elemento di ancoraggio.
- Revoca l'URL dell'oggetto (
url
) chiamandoURL.revokeObjectURL
. Si tratta di un passaggio importante per assicurarsi che la memoria non venga persa nel client.
<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>
Nota
Per indicazioni generali sulla JS posizione e i suggerimenti per le app di produzione, vedere Blazor ASP.NET Core.
Componente seguente:
- Usa l'interoperabilità di flusso di byte nativa per garantire un trasferimento efficiente del file al client.
- Dispone di un metodo denominato
GetFileStream
per recuperare un Stream per il file scaricato sui client. Gli approcci alternativi includono il recupero di un file dall'archiviazione o la generazione dinamica di un file nel codice C#. Per questa dimostrazione, l'app crea un file di 50 KB di dati casuali da una nuova matrice di byte (new byte[]
). i byte vengono incapsulati con un MemoryStream per essere utilizzati come file binario generato dinamicamente dell'esempio. - Il metodo
DownloadFileFromStream
:- Recupera l'oggetto Stream da
GetFileStream
. - Specifica un nome di file quando il file viene salvato nel computer dell'utente. L'esempio seguente denomina il file
quote.txt
. - Esegue il wrapping di Stream in un DotNetStreamReference, che consente di trasmettere i dati del file al client.
- Richiama la
downloadFileFromStream
JS funzione per accettare i dati nel client.
- Recupera l'oggetto Stream da
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);
}
}
Per un componente in un'app sul lato server che deve restituire un Stream per un file fisico, il componente può chiamare File.OpenRead, come illustrato nell'esempio seguente:
private Stream GetFileStream() => File.OpenRead(@"{PATH}");
Nell'esempio precedente il {PATH}
segnaposto è il percorso del file. Il @
prefisso indica che la stringa è una stringa letterale verbatim, che consente l'uso di una barra rovesciata (\
) in un percorso del sistema operativo Windows e di virgolette doppie (""
) all'interno di un singolo elemento nel percorso. In alternativa, evitare il valore letterale stringa (@
) e usare uno degli approcci seguenti:
- Utilizzare le barre rovesciate di escape (
\\
) e le virgolette (\"
). - Usare barre oblique (
/
) nel percorso, che sono supportate su tutte le piattaforme nelle app ASP.NET Core, e virgolette con escape (\"
).
Scaricare da un URL
Questa sezione si applica ai file di dimensioni relativamente grandi, in genere di 250 MB o superiori.
L'approccio consigliato per il download di file relativamente grandi (>= 250 MB) con componenti o file di cui è stato eseguito il rendering interattivo di qualsiasi dimensione per i componenti sottoposti a rendering statico consiste nell'attivare JS un elemento di ancoraggio con il nome e l'URL del file.
L'approccio consigliato per il download di file relativamente grandi (>= 250 MB) consiste nell'attivare JS un elemento di ancoraggio con il nome e l'URL del file.
L'esempio in questa sezione usa un file di download denominato quote.txt
, che viene inserito in una cartella denominata files
nella radice Web dell'app (wwwroot
cartella). L'uso della files
cartella è solo a scopo dimostrativo. È possibile organizzare i file scaricabili in qualsiasi layout di cartella all'interno della radice Web (wwwroot
cartella) preferita, inclusa la gestione dei file direttamente dalla wwwroot
cartella.
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/)
La funzione seguente triggerFileDownload
JS :
- Crea un elemento
HTMLAnchorElement
(<a>
). - Assegna il nome del file (
fileName
) e l'URL (url
) per il download. - Attiva il download attivando un
click
evento sull'elemento di ancoraggio. - Rimuove l'elemento di ancoraggio.
<script>
window.triggerFileDownload = (fileName, url) => {
const anchorElement = document.createElement('a');
anchorElement.href = url;
anchorElement.download = fileName ?? '';
anchorElement.click();
anchorElement.remove();
}
</script>
Nota
Per indicazioni generali sulla JS posizione e i suggerimenti per le app di produzione, vedere Blazor ASP.NET Core.
Il componente di esempio seguente scarica il file dalla stessa origine usata dall'app. Se si tenta di scaricare il file da un'origine diversa, configurare la condivisione di risorse tra le origini (CORS). Per ulteriori informazioni, vedere la sezione Condivisione delle risorse tra le origini (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);
}
}
Per i componenti interattivi, il pulsante nell'esempio precedente chiama il DownloadFileFromURL
gestore per richiamare la funzione JSJavaScript (triggerFileDownload
).
Se il componente adotta il rendering statico lato server (SSR statico), aggiungere un gestore eventi per il pulsante (addEventListener
) per chiamare triggerFileDownload
seguendo le indicazioni riportate in ASP.NET Core Blazor JavaScript con rendering statico lato server (SSR statico).
@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);
}
}
Per i componenti interattivi, il pulsante nell'esempio precedente chiama il DownloadFileFromURL
gestore per richiamare la funzione JSJavaScript (triggerFileDownload
).
Se il componente adotta il rendering statico lato server (SSR statico), aggiungere un gestore eventi per il pulsante (addEventListener
) per chiamare triggerFileDownload
seguendo le indicazioni riportate in ASP.NET Core Blazor JavaScript con rendering statico lato server (SSR statico).
@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);
}
}
Modificare la porta nell'esempio precedente in modo che corrisponda alla porta di sviluppo localhost dell'ambiente.
@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);
}
}
Modificare la porta nell'esempio precedente in modo che corrisponda alla porta di sviluppo localhost dell'ambiente.
Condivisione delle risorse tra origini diverse (CORS)
Senza eseguire ulteriori passaggi per abilitare la condivisione di risorse tra le origini (CORS) per i file che non hanno la stessa origine dell'app, il download dei file non passerà i controlli CORS eseguiti dal browser.
Per altre informazioni su CORS con app ASP.NET Core e altri prodotti e servizi Microsoft che ospitano file per il download, vedere le risorse seguenti:
- Abilitare le richieste cross-origin (CORS) in ASP.NET Core
- Utilizzo di Azure CDN con CORS (documentazione di Azure)
- Supporto CORS (Cross-Origin Resource Sharing) per Azure Storage (REST la documentazione)
- Core Servizi cloud - Configurare CORS per il sito Web e gli asset di archiviazione (modulo Learn)
- Guida di riferimento alla configurazione del modulo IIS CORS (documentazione di IIS)
Risorse aggiuntive
- File statici di ASP.NET Core Blazor
- interoperabilità JavaScript di Blazor ASP.NET Core (JS interop)
- Percorso JavaScript nelle app ASP.NET Core Blazor
- ASP.NET Core Blazor JavaScript con rendering statico lato server (SSR statico)
-
<a>
: elemento Anchor: sicurezza e privacy (documentazione MDN) - Caricamenti di file ASP.NET Core Blazor
-
Blazorrepository GitHub di esempi (
dotnet/blazor-samples
) (come scaricare)