stahování souborů ASP.NET Core Blazor
Poznámka:
Toto není nejnovější verze tohoto článku. Aktuální verzi najdete v tomto článku ve verzi .NET 9.
Upozorňující
Tato verze ASP.NET Core se už nepodporuje. Další informace najdete v tématu .NET a .NET Core Zásady podpory. Aktuální verzi najdete ve verzi .NET 8 tohoto článku.
Důležité
Tyto informace se týkají předběžného vydání produktu, který může být podstatně změněn před komerčním vydáním. Microsoft neposkytuje žádné záruky, výslovné ani předpokládané, týkající se zde uváděných informací.
Aktuální verzi najdete v tomto článku ve verzi .NET 9.
Tento článek vysvětluje, jak stahovat soubory v Blazor aplikacích.
Stažení souborů
Tento článek popisuje přístupy pro následující scénáře, kdy by se soubor neměl otevírat v prohlížeči, ale stahovat a ukládat do klienta:
- Streamování obsahu souboru do nezpracované binární datové vyrovnávací paměti klienta: Obvykle se tento přístup používá pro relativně malé soubory (< 250 MB).
- Stáhněte si soubor přes adresu URL bez streamování: Tento přístup se obvykle používá pro relativně velké soubory (> 250 MB).
Při stahování souborů z jiného původu než aplikace platí důležité informace o sdílení prostředků mezi zdroji (CORS). Další informace najdete v části Sdílení prostředků mezi zdroji (CORS).
Bezpečnostní aspekty
Při poskytování uživatelů s možností stahovat soubory ze serveru buďte opatrní. Cyberattackers může spouštět útoky DoS (Denial of Service), útoky na zneužití rozhraní API nebo se pokoušet o ohrožení sítí a serverů jinými způsoby.
Bezpečnostní kroky, které snižují pravděpodobnost úspěšného útoku:
- Stáhněte si soubory z vyhrazené oblasti pro stahování souborů na serveru, nejlépe z nesystémové jednotky. Použití vyhrazeného umístění usnadňuje ukládání bezpečnostních omezení pro soubory ke stažení. Zakažte oprávnění ke spuštění v oblasti pro stahování souborů.
- Kontroly zabezpečení na straně klienta se dají snadno obejít škodlivými uživateli. Na serveru vždy proveďte také kontroly zabezpečení na straně klienta.
- Nepřijmete soubory od uživatelů nebo jiných nedůvěryhodných zdrojů a pak soubory zpřístupníte k okamžitému stažení, aniž byste u souborů provedli kontroly zabezpečení. Další informace najdete v tématu Nahrání souborů v ASP.NET Core.
Stažení ze streamu
Tato část se týká souborů, které mají obvykle velikost až 250 MB.
Doporučeným přístupem ke stažení relativně malých souborů (<250 MB) je streamování obsahu souboru do nezpracované binární vyrovnávací paměti dat v klientovi pomocí interoperability JavaScriptu (JS). Tento přístup je účinný pro komponenty, které přijímají interaktivní režim vykreslování, ale ne komponenty, které přijímají statické vykreslování na straně serveru (statické SSR).
Doporučeným přístupem ke stažení relativně malých souborů (<250 MB) je streamování obsahu souboru do nezpracované binární vyrovnávací paměti dat v klientovi pomocí interoperability JavaScriptu (JS).
Upozorňující
Přístup v této části přečte obsah souboru do JS ArrayBuffer
souboru . Tento přístup načte celý soubor do paměti klienta, což může ovlivnit výkon. Pokud chcete stáhnout relativně velké soubory (>= 250 MB), doporučujeme postupovat podle pokynů v části Stažení z adresy URL .
downloadFileFromStream
JS Následující funkce:
- Načte zadaný datový proud do objektu
ArrayBuffer
. Blob
Vytvoří pro zabalení objektuArrayBuffer
.- Vytvoří adresu URL objektu, která bude sloužit jako adresa pro stažení souboru.
- Vytvoří (
HTMLAnchorElement
<a>
element). - Přiřadí název souboru () a adresu URL (
fileName
url
) ke stažení. - Aktivuje stahování spuštěním
click
události na elementu ukotvení. - Odebere prvek ukotvení.
- Odvolá adresu URL
url
objektu volánímURL.revokeObjectURL
. Jedná se o důležitý krok k zajištění nevracení paměti v klientovi.
<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>
Poznámka:
Obecné pokyny k JS umístění a doporučení pro produkční aplikace najdete v tématu o umístění JavaScriptu v aplikacích ASP.NET CoreBlazor.
Následující komponenta:
- Používá nativní interoperabilitu bajtů streamování k zajištění efektivního přenosu souboru do klienta.
- Má metodu pojmenovanou
GetFileStream
Stream k načtení souboru, který se stáhne do klientů. Mezi alternativní přístupy patří načtení souboru z úložiště nebo dynamické generování souboru v kódu jazyka C#. Pro tuto ukázku aplikace vytvoří soubor 50 kB náhodných dat z nového bajtového pole (new byte[]
). Bajty jsou zabalené jako MemoryStream dynamicky vygenerovaný binární soubor příkladu. - Metoda
DownloadFileFromStream
:- Načte Stream z
GetFileStream
. - Určuje název souboru, když je soubor uložen na počítači uživatele. Následující příklad pojmenuje soubor
quote.txt
. - Zabalí soubor do objektu Stream DotNetStreamReference, který umožňuje streamování dat souboru do klienta.
downloadFileFromStream
JS Vyvolá funkci pro přijetí dat v klientovi.
- Načte 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);
}
}
Pro komponentu v aplikaci na straně serveru, která musí vrátit Stream pro fyzický soubor, může komponenta volat File.OpenRead, jak ukazuje následující příklad:
private Stream GetFileStream() => File.OpenRead(@"{PATH}");
V předchozím příkladu {PATH}
je zástupný symbol cestou k souboru. Předpona @
označuje, že řetězec je doslovný řetězcový literál, který umožňuje použití zpětných lomítek (\
) v cestě operačního systému Windows a vložené dvojité uvozovky (""
) pro jednu uvozovku v cestě. Případně se vyhněte řetězcovém literálu (@
) a použijte některý z následujících přístupů:
- Použijte uvozovky (
\\
) a uvozovky (\"
). - Použijte lomítka (
/
) v cestě, které jsou podporovány napříč platformami v aplikacích ASP.NET Core a uvozovky (\"
).
Stažení z adresy URL
Tato část se týká souborů, které jsou relativně velké, obvykle 250 MB nebo větší.
Doporučený postup pro stahování relativně velkých souborů (>= 250 MB) s interaktivně vykreslenými komponentami nebo soubory libovolné velikosti pro staticky vykreslené komponenty je použít JS k aktivaci elementu ukotvení s názvem a adresou URL souboru.
Doporučeným přístupem ke stažení relativně velkých souborů (>= 250 MB) je použití JS k aktivaci elementu ukotvení s názvem a adresou URL souboru.
Příklad v této části používá soubor ke stažení s názvem quote.txt
, který se umístí do složky pojmenované files
ve webovém kořenovém adresáři aplikace (wwwroot
složce). Použití files
složky je pouze pro demonstrační účely. Soubory ke stažení můžete uspořádat v libovolném rozložení složek v kořenovém adresáři webu (wwwroot
složce), které chcete, včetně poskytování souborů přímo ze wwwroot
složky.
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/)
triggerFileDownload
JS Následující funkce:
- Vytvoří (
HTMLAnchorElement
<a>
element). - Přiřadí název souboru () a adresu URL (
fileName
url
) ke stažení. - Aktivuje stahování spuštěním
click
události na elementu ukotvení. - Odebere prvek ukotvení.
<script>
window.triggerFileDownload = (fileName, url) => {
const anchorElement = document.createElement('a');
anchorElement.href = url;
anchorElement.download = fileName ?? '';
anchorElement.click();
anchorElement.remove();
}
</script>
Poznámka:
Obecné pokyny k JS umístění a doporučení pro produkční aplikace najdete v tématu o umístění JavaScriptu v aplikacích ASP.NET CoreBlazor.
Následující ukázková komponenta stáhne soubor ze stejného původu, který aplikace používá. Pokud se o stažení souboru pokusíte z jiného zdroje, nakonfigurujte sdílení prostředků mezi zdroji (CORS). Další informace najdete v části Sdílení prostředků mezi zdroji (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);
}
}
U interaktivních komponent tlačítko v předchozím příkladu volá obslužnou rutinu DownloadFileFromURL
pro vyvolání funkce triggerFileDownload
JavaScriptu (JS).
Pokud komponenta přijímá statické vykreslování na straně serveru (statické SSR), přidejte obslužnou rutinu události pro tlačítko (addEventListener
(dokumentace MDN)) k volání triggerFileDownload
podle pokynů v ASP.NET Core Blazor JavaScriptu se statickým vykreslováním na straně serveru (statická 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);
}
}
U interaktivních komponent tlačítko v předchozím příkladu volá obslužnou rutinu DownloadFileFromURL
pro vyvolání funkce triggerFileDownload
JavaScriptu (JS).
Pokud komponenta přijímá statické vykreslování na straně serveru (statické SSR), přidejte obslužnou rutinu události pro tlačítko (addEventListener
(dokumentace MDN)) k volání triggerFileDownload
podle pokynů v ASP.NET Core Blazor JavaScriptu se statickým vykreslováním na straně serveru (statická 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);
}
}
Změňte port v předchozím příkladu tak, aby odpovídal vývojovému portu místního hostitele vašeho prostředí.
@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);
}
}
Změňte port v předchozím příkladu tak, aby odpovídal vývojovému portu místního hostitele vašeho prostředí.
Cross-Origin Resource Sharing (CORS)
Bez dalších kroků povolení sdílení prostředků mezi zdroji (CORS) pro soubory, které nemají stejný zdroj jako aplikace, stahování souborů neprojde kontrolami CORS provedenými prohlížečem.
Další informace o CORS s aplikacemi ASP.NET Core a dalšími produkty a službami Microsoftu, které hostují soubory ke stažení, najdete v následujících zdrojích informací:
- Povolení žádostí mezi zdroji (CORS) v ASP.NET Core
- Použití Azure CDN s CORS (dokumentace k Azure)
- Podpora sdílení prostředků mezi zdroji (CORS) pro Azure Storage (REST dokumentace)
- Základní cloudové služby – Nastavení CORS pro prostředky webu a úložiště (modul Learn)
- Referenční informace ke konfiguraci modulu CORS služby IIS (dokumentace ke službě IIS)
Další materiály
- ASP.NET základních Blazor statických souborů
- Blazor ASP.NET základní interoperabilita JavaScriptu (JSinteroperabilita)
- Umístění JavaScriptu v aplikacích ASP.NET Core Blazor
- ASP.NET Core Blazor JavaScript se statickým vykreslováním na straně serveru (statické SSR)
<a>
: Element Anchor: Security and privacy (dokumentace k MDN)- nahrávání souborů ASP.NET Core Blazor
- Blazorukázky úložiště GitHub () (
dotnet/blazor-samples
postup stažení)