download di file di Blazor base ASP.NET
Nota
Questa non è la versione più recente di questo articolo. Per la versione corrente, vedere la versione .NET 8 di questo articolo.
Avviso
Questa versione di ASP.NET Core non è più supportata. Per altre informazioni, vedere Criteri di supporto di .NET e .NET Core. Per la versione corrente, vedere la versione .NET 8 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 8 di questo articolo.
Questo articolo illustra come scaricare i file nelle Blazor app.
Download di file
I file possono essere scaricati dagli asset statici dell'app o da qualsiasi altra posizione:
- ASP.NET le app di base usano il middleware map static assets o static file middleware per gestire i file ai client delle app lato server. Per altre informazioni, vedere File statici in ASP.NET Core Blazor.
- Le indicazioni contenute in questo articolo si applicano anche ad altri tipi di file server che non usano .NET, ad esempio rete per la distribuzione di contenuti (CDN).
- ASP.NET le app di base usano il middleware dei file statici per gestire i file ai client di app lato server.
- Le indicazioni contenute in questo articolo si applicano anche ad altri tipi di file server che non usano .NET, ad esempio rete per la distribuzione di contenuti (CDN).
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 altre informazioni, vedere 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 un flusso
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 interoperabilità JavaScript (JS). 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 interoperabilità JavaScript (JS).
Avviso
L'approccio 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 fornito in un oggetto
ArrayBuffer
. - Crea un
Blob
oggetto per eseguire il wrapping dell'oggettoArrayBuffer
. - 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 Posizione JavaScript nelle app ASP.NET CoreBlazor.
Componente seguente:
- Usa l'interoperabilità di flusso di byte nativa per garantire un trasferimento efficiente del file nel client.
- Dispone di un metodo denominato
GetFileStream
per recuperare un Stream oggetto per il file scaricato nei 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 oggetto da usare come file binario generato in modo dinamico 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 DotNetStreamReferenceoggetto , 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
<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 lato server che deve restituire un Stream oggetto 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 è un valore letterale stringa verbatim, che consente l'uso di barre rovesciata (\
) in un percorso del sistema operativo Windows e virgolette doppie incorporate (""
) per una virgoletta singola nel percorso. In alternativa, evitare il valore letterale stringa (@
) e usare uno degli approcci seguenti:
- Usare barre rovesciate di escape () e virgolette (
\\
\"
). - Usare le barre (
/
) nel percorso, supportate tra le piattaforme nelle app ASP.NET Core e virgolette di 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/)
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 Posizione JavaScript nelle app ASP.NET CoreBlazor.
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 altre informazioni, vedere la sezione Condivisione 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 triggerFileDownload
JavaScript (JS).
Se il componente adotta il rendering statico lato server (SSR statico), aggiungere un gestore eventi per il pulsante (addEventListener
(documentazione MDN) 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.
Cross-Origin Resource Sharing (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 tra le origini (CORS) in ASP.NET Core
- Uso di Rete CDN di Azure con CORS (documentazione di Azure)
- Supporto CORS (Cross-Origin Resource Sharing) per Archiviazione di Azure (REST 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
- interoperabilità javaScript di Blazor base ASP.NET (JS interoperabilità)
- Percorso JavaScript nelle app ASP.NET Core Blazor
- ASP.NET Core Blazor JavaScript con rendering statico lato server (SSR statico)
<a>
: elemento Anchor: Security e privacy (documentazione mdn)- ASP.NET caricamenti di file di base Blazor
- Blazorrepository GitHub di esempi () (
dotnet/blazor-samples
come scaricare)