pobieranie plików ASP.NET Core Blazor
Uwaga
Nie jest to najnowsza wersja tego artykułu. Aby zapoznać się z bieżącą wersją, zobacz wersję tego artykułu platformy .NET 9.
Ważne
Te informacje odnoszą się do produktu w wersji wstępnej, który może zostać znacząco zmodyfikowany, zanim zostanie wydany komercyjnie. Firma Microsoft nie udziela żadnych gwarancji, jawnych lub domniemanych, w odniesieniu do informacji podanych w tym miejscu.
Aby zapoznać się z bieżącą wersją, zobacz wersję tego artykułu platformy .NET 9.
W tym artykule wyjaśniono, jak pobierać pliki w Blazor aplikacjach.
Operacje pobierania plików
W tym artykule opisano podejścia do następujących scenariuszy, w których plik nie powinien być otwierany przez przeglądarkę, ale pobierany i zapisywany na kliencie:
- Przesyłanie strumieniowe zawartości pliku do nieprzetworzonego buforu danych binarnych na kliencie: zazwyczaj to podejście jest używane w przypadku stosunkowo małych plików (< 250 MB).
- Pobierz plik za pośrednictwem adresu URL bez przesyłania strumieniowego: zazwyczaj to podejście jest używane w przypadku stosunkowo dużych plików (> 250 MB).
Podczas pobierania plików z innego źródła niż aplikacja mają zastosowanie zagadnienia dotyczące współużytkowania zasobów między źródłami (CORS). Aby uzyskać więcej informacji, zobacz sekcję Współużytkowanie zasobów między źródłami (CORS).
Zagadnienia dotyczące zabezpieczeń
Należy zachować ostrożność podczas zapewniania użytkownikom możliwości pobierania plików z serwera. Cyberataki mogą wykonywać ataki typu "odmowa usługi" , ataki wykorzystujące interfejs API lub próbować naruszyć bezpieczeństwo sieci i serwerów w inny sposób.
Kroki zabezpieczeń, które zmniejszają prawdopodobieństwo pomyślnego ataku, to:
- Pobierz pliki z dedykowanego obszaru pobierania plików na serwerze, najlepiej z dysku innego niż system. Użycie dedykowanej lokalizacji ułatwia nakładanie ograniczeń zabezpieczeń na pliki do pobrania. Wyłącz uprawnienia wykonywania w obszarze pobierania pliku.
- Kontrole zabezpieczeń po stronie klienta są łatwe do obejścia przez złośliwych użytkowników. Zawsze przeprowadzaj kontrole zabezpieczeń po stronie klienta na serwerze.
- Nie odbieraj plików od użytkowników ani innych niezaufanych źródeł, a następnie udostępniaj pliki do natychmiastowego pobierania bez przeprowadzania kontroli zabezpieczeń plików. Aby uzyskać więcej informacji, zobacz Przekazywanie plików w programie ASP.NET Core.
Pobieranie ze strumienia
Ta sekcja dotyczy plików, które zazwyczaj mają rozmiar do 250 MB.
Zalecanym podejściem do pobierania stosunkowo małych plików (<250 MB) jest przesyłanie strumieniowe zawartości plików do nieprzetworzonego buforu danych binarnych na kliencie za pomocą międzyoperacyjnego języka JavaScript (JS). Takie podejście jest skuteczne w przypadku składników, które przyjmują interaktywny tryb renderowania, ale nie składniki, które przyjmują statyczne renderowanie po stronie serwera (statyczny przewodnik SSR).
Zalecanym podejściem do pobierania stosunkowo małych plików (<250 MB) jest przesyłanie strumieniowe zawartości plików do nieprzetworzonego buforu danych binarnych na kliencie za pomocą międzyoperacyjnego języka JavaScript (JS).
Ostrzeżenie
Podejście w tej sekcji odczytuje zawartość pliku do elementu JS ArrayBuffer
. Takie podejście powoduje załadowanie całego pliku do pamięci klienta, co może obniżyć wydajność. Aby pobrać stosunkowo duże pliki (>= 250 MB), zalecamy wykonanie wskazówek w sekcji Pobieranie z adresu URL .
Następująca downloadFileFromStream
JS funkcja:
- Odczytuje udostępniony strumień do elementu
ArrayBuffer
. - Tworzy obiekt w
Blob
celu opakowania .ArrayBuffer
- Tworzy adres URL obiektu, który będzie służył jako adres pobierania pliku.
- Tworzy element
HTMLAnchorElement
(<a>
). - Przypisuje nazwę pliku (
fileName
) i adres URL (url
) do pobrania. - Wyzwala pobieranie, uruchamiając
click
zdarzenie w elemecie kotwicy. - Usuwa element kotwicy.
- Odwołuje adres URL obiektu (
url
) przez wywołanie metodyURL.revokeObjectURL
. Jest to ważny krok, aby upewnić się, że pamięć nie wyciekła na kliencie.
<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>
Uwaga
Aby uzyskać ogólne wskazówki dotyczące JS lokalizacji i naszych zaleceń dotyczących aplikacji produkcyjnych, zobacz Lokalizacja języka JavaScript w aplikacjach ASP.NET CoreBlazor.
Następujący składnik:
- Używa natywnego międzyoperacyjności przesyłania strumieniowego bajtów w celu zapewnienia wydajnego transferu pliku do klienta.
- Ma metodę o nazwie
GetFileStream
, aby pobrać Stream plik pobrany do klientów. Alternatywne podejścia obejmują pobieranie pliku z magazynu lub dynamiczne generowanie pliku w kodzie języka C#. Na potrzeby tego pokazu aplikacja tworzy plik 50 KB danych losowych z nowej tablicy bajtów (new byte[]
). Bajty są opakowane z wartością , MemoryStream która będzie służyć jako dynamicznie generowany plik binarny przykładu. - Metoda
DownloadFileFromStream
:- Pobiera element Stream z
GetFileStream
. - Określa nazwę pliku, gdy plik jest zapisywany na komputerze użytkownika. Poniższy przykład nazywa plik
quote.txt
. - Zawija element Stream w obiekcie DotNetStreamReference, który umożliwia przesyłanie strumieniowe danych plików do klienta.
- Wywołuje funkcję w celu zaakceptowania danych na kliencie
downloadFileFromStream
JS .
- Pobiera element Stream z
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);
}
}
W przypadku składnika w aplikacji po stronie serwera, który musi zwrócić Stream element dla pliku fizycznego, składnik może wywołać metodę File.OpenRead, jak pokazano w poniższym przykładzie:
private Stream GetFileStream() => File.OpenRead(@"{PATH}");
W poprzednim przykładzie {PATH}
symbol zastępczy jest ścieżką do pliku. Prefiks @
wskazuje, że ciąg jest literałem ciągu dosłownego, który umożliwia użycie ukośników odwrotnych (\
) w ścieżce systemu operacyjnego Windows i osadzonych podwójnych cudzysłowów (""
) dla pojedynczego cudzysłowu w ścieżce. Alternatywnie należy unikać literału ciągu (@
) i użyć jednej z następujących metod:
- Użyj ukośników odwrotnych (
\\
) i cudzysłowów (\"
). - Użyj ukośników (
/
) w ścieżce, które są obsługiwane na różnych platformach w aplikacjach ASP.NET Core i cudzysłowów ucieczki (\"
).
Pobieranie z adresu URL
Ta sekcja dotyczy plików, które są stosunkowo duże, zazwyczaj 250 MB lub większe.
Zalecaną metodą pobierania stosunkowo dużych plików (>= 250 MB) z interaktywnie renderowanych składników lub plików o dowolnym rozmiarze statycznie renderowanych składników jest JS użycie do wyzwalania elementu kotwicy z nazwą i adresem URL pliku.
Zalecane podejście do pobierania stosunkowo dużych plików (>= 250 MB) polega na JS wyzwoleniu elementu kotwicy z nazwą i adresem URL pliku.
W przykładzie w tej sekcji jest używany plik pobierania o nazwie quote.txt
, który znajduje się w folderze o nazwie files
w katalogu głównym aplikacji (wwwroot
folder). Korzystanie z files
folderu jest przeznaczone tylko do celów demonstracyjnych. Pliki do pobrania można organizować w dowolnym układzie folderów w preferowanym folderze głównym (wwwroot
folderze), w tym obsługiwać wwwroot
pliki bezpośrednio z folderu.
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/)
Następująca triggerFileDownload
JS funkcja:
- Tworzy element
HTMLAnchorElement
(<a>
). - Przypisuje nazwę pliku (
fileName
) i adres URL (url
) do pobrania. - Wyzwala pobieranie, uruchamiając
click
zdarzenie w elemecie kotwicy. - Usuwa element kotwicy.
<script>
window.triggerFileDownload = (fileName, url) => {
const anchorElement = document.createElement('a');
anchorElement.href = url;
anchorElement.download = fileName ?? '';
anchorElement.click();
anchorElement.remove();
}
</script>
Uwaga
Aby uzyskać ogólne wskazówki dotyczące JS lokalizacji i naszych zaleceń dotyczących aplikacji produkcyjnych, zobacz Lokalizacja języka JavaScript w aplikacjach ASP.NET CoreBlazor.
Poniższy przykładowy składnik pobiera plik z tego samego źródła, którego używa aplikacja. Jeśli próba pobrania pliku zostanie podjęta z innego źródła, skonfiguruj współużytkowanie zasobów między źródłami (CORS). Aby uzyskać więcej informacji, zobacz sekcję Współużytkowanie zasobów między źródłami (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);
}
}
W przypadku składników interaktywnych przycisk w poprzednim przykładzie wywołuje DownloadFileFromURL
procedurę obsługi w celu wywołania funkcji triggerFileDownload
JavaScript (JS).
Jeśli składnik przyjmuje statyczne renderowanie po stronie serwera (statyczny przewodnik SSR), dodaj procedurę obsługi zdarzeń dla przycisku (addEventListener
dokumentacja MDN)), aby wywołać następujące triggerFileDownload
wskazówki w ASP.NET Core Blazor JavaScript ze statycznym renderowaniem po stronie serwera (statyczne SSR).
@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);
}
}
W przypadku składników interaktywnych przycisk w poprzednim przykładzie wywołuje DownloadFileFromURL
procedurę obsługi w celu wywołania funkcji triggerFileDownload
JavaScript (JS).
Jeśli składnik przyjmuje statyczne renderowanie po stronie serwera (statyczny przewodnik SSR), dodaj procedurę obsługi zdarzeń dla przycisku (addEventListener
dokumentacja MDN)), aby wywołać następujące triggerFileDownload
wskazówki w ASP.NET Core Blazor JavaScript ze statycznym renderowaniem po stronie serwera (statyczne SSR).
@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);
}
}
Zmień port w poprzednim przykładzie, aby był zgodny z portem programowania localhost środowiska.
@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);
}
}
Zmień port w poprzednim przykładzie, aby był zgodny z portem programowania localhost środowiska.
Udostępnianie zasobów z różnych źródeł (CORS)
Bez wykonywania dalszych kroków w celu włączenia współużytkowania zasobów między źródłami (CORS) dla plików, które nie mają tego samego źródła co aplikacja, pobieranie plików nie będzie przechodzić testów CORS wykonanych przez przeglądarkę.
Aby uzyskać więcej informacji na temat mechanizmu CORS z aplikacjami ASP.NET Core i innymi produktami i usługami firmy Microsoft hostujących pliki do pobrania, zobacz następujące zasoby:
- Włączanie żądań między źródłami (CORS) w usłudze ASP.NET Core
- Korzystanie z usługi Azure CDN z mechanizmem CORS (dokumentacja platformy Azure)
- Obsługa współużytkowania zasobów między źródłami (CORS) dla usługi Azure Storage (REST dokumentacja)
- Podstawowe usługi w chmurze — konfigurowanie mechanizmu CORS dla witryny internetowej i zasobów magazynu (moduł Learn)
- Dokumentacja konfiguracji modułu CORS usług IIS (dokumentacja usług IIS)
Dodatkowe zasoby
- ASP.NET Core Blazor plików statycznych
- współdziałanie ASP.NET Core Blazor w języku JavaScript (JS międzyoperacja)
- Lokalizacja języka JavaScript w aplikacjach ASP.NET Core Blazor
- ASP.NET Core Blazor JavaScript ze statycznym renderowaniem po stronie serwera (statycznym usługą SSR)
<a>
: Element Anchor: Security and privacy (Dokumentacja MDN)- przekazywanie plików ASP.NET Core Blazor
- Blazorprzykładowe repozytorium GitHub () (
dotnet/blazor-samples
jak pobrać)