ASP.NET Core Blazor dosya indirmeleri
Uyarı
ASP.NET Core'un bu sürümü artık desteklenmiyor. Daha fazla bilgi için bkz . .NET ve .NET Core Destek İlkesi. Geçerli sürüm için bu makalenin .NET 8 sürümüne bakın.
Bu makalede, uygulamalardaki Blazor dosyaların nasıl indirilmesi açıklanır.
Dosya indirme işlemleri
Bu makale, bir dosyanın bir tarayıcı tarafından açılmaması ancak istemciye indirilip kaydedilmesi gereken aşağıdaki senaryolara yönelik yaklaşımları kapsar:
- İstemcideki ham ikili veri arabelleğine dosya içeriği akışı yapma: Bu yaklaşım genellikle nispeten küçük dosyalar (< 250 MB) için kullanılır.
- Akışı olmayan bir URL aracılığıyla dosya indirme: Genellikle, bu yaklaşım nispeten büyük dosyalar (> 250 MB) için kullanılır.
Uygulamadan farklı bir kaynaktan dosya indirirken Çıkış Noktaları Arası Kaynak Paylaşımı (CORS) konusunda dikkat edilmesi gerekenler geçerlidir. Daha fazla bilgi için Çıkış Noktaları Arası Kaynak Paylaşımı (CORS) bölümüne bakın.
Güvenlik konuları
Kullanıcılara bir sunucudan dosya indirme olanağı sağlarken dikkatli olun. Siber saldırganlar Hizmet Reddi (DoS) saldırıları, API'den yararlanma saldırıları yürütebilir veya ağları ve sunucuları başka yollarla tehlikeye atabilir.
Başarılı bir saldırı olasılığını azaltan güvenlik adımları şunlardır:
- Dosyaları, tercihen sistem dışı bir sürücüden sunucudaki ayrılmış bir dosya indirme alanından indirin. Ayrılmış bir konum kullanmak, indirilebilir dosyalara güvenlik kısıtlamaları uygulamayı kolaylaştırır. Dosya indirme alanında yürütme izinlerini devre dışı bırakın.
- İstemci tarafı güvenlik denetimleri, kötü amaçlı kullanıcılar tarafından kolayca aşılır. Her zaman sunucuda da istemci tarafı güvenlik denetimleri gerçekleştirin.
- Kullanıcılardan veya diğer güvenilmeyen kaynaklardan dosya almayın ve ardından dosyalar üzerinde güvenlik denetimleri gerçekleştirmeden dosyaları anında indirilmeye hazır hale getirin. Daha fazla bilgi için bkz . ASP.NET Core'da dosyaları karşıya yükleme.
Akıştan indirme
Bu bölüm genellikle boyutu 250 MB'a kadar olan dosyalar için geçerlidir.
Görece küçük dosyaları (<250 MB) indirmek için önerilen yaklaşım, javaScript (JS) birlikte çalışma özelliğiyle istemcideki ham ikili veri arabelleğine dosya içeriği akışı yapmaktır. Bu yaklaşım, etkileşimli işleme modunu benimseyen ancak statik sunucu tarafı işlemeyi (statik SSR) benimseyen bileşenler için geçerli değildir.
Görece küçük dosyaları (<250 MB) indirmek için önerilen yaklaşım, javaScript (JS) birlikte çalışma özelliğiyle istemcideki ham ikili veri arabelleğine dosya içeriği akışı yapmaktır.
Uyarı
Bu bölümdeki yaklaşım dosyanın içeriğini olarak JS ArrayBuffer
okur. Bu yaklaşım, dosyanın tamamını istemcinin belleğine yükler ve bu da performansı bozabilir. Görece büyük dosyaları (>= 250 MB) indirmek için URL'den indirme bölümündeki yönergeleri takip etmenizi öneririz.
Aşağıdaki downloadFileFromStream
JS işlev:
- Sağlanan akışı bir
ArrayBuffer
içine okur. - kaydırmak
ArrayBuffer
için birBlob
oluşturur. - Dosyanın indirme adresi olarak hizmet vermek için bir nesne URL'si oluşturur.
- Bir
HTMLAnchorElement
(<a>
öğesi oluşturur. - İndirme için dosyanın adını (
fileName
) ve URL'sini (url
) atar. - Anchor öğesinde bir
click
olay tetikleyerek indirmeyi tetikler. - Tutturucu öğesini kaldırır.
- çağırarak
URL.revokeObjectURL
nesne URL'sini (url
) iptal eder. Bu, istemcide belleğin sızmadığından emin olmak için önemli bir adımdır.
<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>
Not
Konum hakkında genel yönergeler JS ve üretim uygulamalarına yönelik önerilerimiz için bkz . ASP.NET Core Blazor uygulamalarında JavaScript konumu.
Aşağıdaki bileşen:
- Dosyanın istemciye verimli bir şekilde aktarılmasını sağlamak için yerel bayt akışlı birlikte çalışma kullanır.
- İstemcilere indirilen dosya için almak Stream için adlı
GetFileStream
bir yöntemi vardır. Alternatif yaklaşımlar arasında depolama alanından dosya alma veya C# kodunda dinamik olarak dosya oluşturma yer alır. Bu gösterim için uygulama, yeni bir bayt dizisinden (new byte[]
) rastgele verilerden oluşan 50 KB'lık bir dosya oluşturur. Baytlar, örneğin dinamik olarak oluşturulan ikili dosyası olarak hizmet vermek için ile MemoryStream sarmalanmıştır. - Yöntemi
DownloadFileFromStream
:- 'den
GetFileStream
öğesini Stream alır. - Dosya kullanıcının makinesine kaydedildiğinde bir dosya adı belirtir. Aşağıdaki örnek dosyasını
quote.txt
adlandırın. - dosya verilerinin Stream istemciye akışına izin veren bir DotNetStreamReferenceiçinde sarmalar.
- İstemcideki
downloadFileFromStream
JS verileri kabul etmek için işlevini çağırır.
- 'den
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);
}
}
Sunucu tarafı uygulamasında fiziksel bir dosya için döndürmesi Stream gereken bir bileşen için, aşağıdaki örnekte gösterildiği gibi bileşen öğesini çağırabilir File.OpenRead:
private Stream GetFileStream() => File.OpenRead(@"{PATH}");
Yukarıdaki örnekte, {PATH}
yer tutucu dosyanın yoludur. Ön @
ek, dizenin bir Windows işletim sistemi yolunda ters eğik çizgi (\
) ve yoldaki tek tırnak için katıştırılmış çift tırnak (""
) kullanımına izin veren düz bir dize değişmez değeri olduğunu gösterir. Alternatif olarak, dize değişmez değerlerinden (@
) kaçının ve aşağıdaki yaklaşımlardan birini kullanın:
- Kaçış ters eğik çizgilerini (
\\
) ve tırnakları (\"
) kullanın. - ASP.NET Core uygulamalarında platformlar arasında desteklenen yolda eğik çizgi (
/
) ve kaçış tırnak işaretleri (\"
) kullanın.
URL'den indirme
Bu bölüm, genellikle 250 MB veya daha büyük nispeten büyük dosyalar için geçerlidir.
Statik olarak işlenmiş bileşenler için etkileşimli olarak işlenmiş bileşenler veya herhangi bir boyuttaki dosyalar ile nispeten büyük dosyaları (>= 250 MB) indirmek için önerilen yaklaşım, dosyanın adı ve URL'si ile bir tutturucu öğesini tetikleme amacıyla kullanmaktır JS .
Nispeten büyük dosyaları (>= 250 MB) indirmek için önerilen yaklaşım, dosyanın adı ve URL'si ile bir tutturucu öğesini tetikleme amacıyla kullanmaktır JS .
Bu bölümdeki örnekte, uygulamanın web kökünde (wwwroot
klasöründe) quote.txt
adlı bir klasöre yerleştirilen adlı files
bir indirme dosyası kullanılır. Klasörün kullanımı files
yalnızca gösterim amaçlıdır. İndirilebilir dosyaları, dosyaları doğrudan klasörden sunma dahil olmak üzere, tercih ettiğiniz web kökündeki (wwwroot
klasör) herhangi bir klasör düzeninde wwwroot
düzenleyebilirsiniz.
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/)
Aşağıdaki triggerFileDownload
JS işlev:
- Bir
HTMLAnchorElement
(<a>
öğesi oluşturur. - İndirme için dosyanın adını (
fileName
) ve URL'sini (url
) atar. - Anchor öğesinde bir
click
olay tetikleyerek indirmeyi tetikler. - Tutturucu öğesini kaldırır.
<script>
window.triggerFileDownload = (fileName, url) => {
const anchorElement = document.createElement('a');
anchorElement.href = url;
anchorElement.download = fileName ?? '';
anchorElement.click();
anchorElement.remove();
}
</script>
Not
Konum hakkında genel yönergeler JS ve üretim uygulamalarına yönelik önerilerimiz için bkz . ASP.NET Core Blazor uygulamalarında JavaScript konumu.
Aşağıdaki örnek bileşen, dosyayı uygulamanın kullandığı kaynaktan indirir. Dosya indirme işlemi farklı bir kaynaktan yapılmaya çalışılırsa Çıkış Noktaları Arası Kaynak Paylaşımı'nı (CORS) yapılandırın. Daha fazla bilgi için Çıkış Noktaları Arası Kaynak Paylaşımı (CORS) bölümüne bakın.
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);
}
}
Etkileşimli bileşenler için, önceki örnekteki düğme JavaScript (JS) işlevini triggerFileDownload
çağırmak için işleyiciyi çağırırDownloadFileFromURL
.
Bileşen statik sunucu tarafı işlemeyi (statik SSR) benimsiyorsa, statik sunucu tarafı işleme (statik SSR) ile ASP.NET Core JavaScript'teki yönergeleri izleyerek çağırmak triggerFileDownload
üzere düğmeaddEventListener
((MDN belgeleri)) için bir olay işleyicisi ekleyin.Blazor
@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);
}
}
Etkileşimli bileşenler için, önceki örnekteki düğme JavaScript (JS) işlevini triggerFileDownload
çağırmak için işleyiciyi çağırırDownloadFileFromURL
.
Bileşen statik sunucu tarafı işlemeyi (statik SSR) benimsiyorsa, statik sunucu tarafı işleme (statik SSR) ile ASP.NET Core JavaScript'teki yönergeleri izleyerek çağırmak triggerFileDownload
üzere düğmeaddEventListener
((MDN belgeleri)) için bir olay işleyicisi ekleyin.Blazor
@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);
}
}
Önceki örnekteki bağlantı noktasını ortamınızın localhost geliştirme bağlantı noktasıyla eşleşecek şekilde değiştirin.
@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);
}
}
Önceki örnekteki bağlantı noktasını ortamınızın localhost geliştirme bağlantı noktasıyla eşleşecek şekilde değiştirin.
Çıkış Noktaları Arası Kaynak Paylaşma (CORS)
Uygulamayla aynı kaynağa sahip olmayan dosyalar için Çıkış Noktaları Arası Kaynak Paylaşımı'nı (CORS) etkinleştirmeye yönelik başka adımlar atılmadan, dosyaların indirilmesi tarayıcı tarafından yapılan CORS denetimlerini geçemez.
ASP.NET Core uygulamalarıyla CORS ve indirilme amacıyla dosya barındıran diğer Microsoft ürün ve hizmetleri hakkında daha fazla bilgi için aşağıdaki kaynaklara bakın:
- ASP.NET Core'da Çıkış Noktaları Arası İstekleri (CORS) Etkinleştirme
- AZURE CDN'yi CORS ile kullanma (Azure belgeleri)
- Azure Depolama için Çıkış Noktaları Arası Kaynak Paylaşımı (CORS) desteği (REST belgeler)
- Temel Bulut Hizmetleri - Web siteniz ve depolama varlıklarınız için CORS'i ayarlama (Learn modülü)
- IIS CORS modülü Yapılandırma Başvurusu (IIS belgeleri)
Ek kaynaklar
- ASP.NET Core Blazor statik dosyaları
- ASP.NET Core Blazor JavaScript birlikte çalışabilirliği (JS birlikte çalışma)
- ASP.NET Core Blazor uygulamalarında JavaScript konumu
- Statik sunucu tarafı işleme (statik SSR) ile ASP.NET Core Blazor JavaScript
<a>
: Anchor öğesi: Güvenlik ve privacy (MDN belgeleri)- ASP.NET Core Blazor dosyası karşıya yüklemeleri
- Blazorörnekler GitHub deposu () (
dotnet/blazor-samples
nasıl indirilir)
ASP.NET Core