HTML düğmesine veya JavaScript'e tıklandığında dosya indirme işlemi nasıl tetiklenir


434

Bu çılgınca ama bunu nasıl yapacağımı bilmiyorum ve kelimelerin ne kadar yaygın olduğu nedeniyle, arama motorlarında neye ihtiyacım olduğunu bulmak zor. Bunun cevaplaması kolay bir şey olacağını düşünüyorum.

Ben basit bir dosya indirme, bu aynı şeyi istiyorum:

<a href="file.doc">Download!</a>

Ama bir HTML düğmesi kullanmak istiyorum, örneğin:

<input type="button" value="Download!">
<button>Download!</button>

Benzer şekilde, JavaScript yoluyla basit bir indirme işlemini başlatmak mümkün müdür?

$("#fileRequest").click(function(){ /* code to download? */ });

Kesinlikle bir düğmeye benzeyen bir çapa oluşturmak, herhangi bir arka uç komut dosyası kullanmak veya sunucu üstbilgileri veya mime türleri ile karışıklık için bir yol aramıyorum .


15
Teşekkürler "nasıl javascript bir dosya indirme tetiklemek için" gelecekteki aramalar için çok daha hızlı cevap verecektir.
Danubian Sailor

Yanıtlar:


278

Düğme için şunları yapabilirsiniz

<form method="get" action="file.doc">
   <button type="submit">Download!</button>
</form>

Form etiketini kaydedebilir ve düğme etiketine bir tıklama ekleyebilirsiniz.
Florian Leitgeb

12
tetikleyici olarak çalışmaz, sadece URL'ye 'a' etiketi olarak yönlendirin.
fdrv

7
Bu daha iyi çalışır: <a href="path_to_file" download="proposed_file_name"> İndirin </a>
kscius

11
@kscius bugün bile indirme özelliği IE 11'de desteklenmemektedir (artık Edge'de desteklenmektedir) ve Safari'de desteklenmemektedir. Yanıtın ilk olarak gönderildiği 2012 yılında, herhangi bir büyük tarayıcıda desteklenmedi.
Cfreak

1
düğme stilinde bir çapaya sahip olmak ve düğmeli bir forma sahip olmak arasındaki fark nedir?
Andrei Epure

444

Bir indirme işlemini HTML5 downloadözelliğiyle tetikleyebilirsiniz .

<a href="path_to_file" download="proposed_file_name">Download</a>

Nerede:

  • path_to_fileaynı kaynaktan gelen bir URL'ye çözümlenen bir yoldur . Bu, sayfanın ve dosyanın aynı etki alanını, alt etki alanını, protokolü (HTTP ve HTTPS) ve bağlantı noktasını (belirtilmişse) paylaşması gerektiği anlamına gelir. İstisnalar vardır blob:ve data:(ki her zaman iş) ve file:(asla işe yaramaz olan).
  • proposed_file_namekaydedilecek dosya adıdır. Boşsa, tarayıcı varsayılan olarak dosyanın adını kullanır.

Belgeler: MDN , İndirme sırasında HTML Standardıdownload , HTML Standardı açık , CanIUse


37
Safari ve belirli IE sürümleri ile çalışma
Mohamed Hussain

4
Çoğu kullanım vakasını bir arada kullanmak downloadve target="_blank"yeterli görünmektedir. Anlayan tarayıcılar downloadbir indirme olarak kabul eder, aksi takdirde yeni bir sekmede açılır.
MK10

10
Bu yalnızca bir etiket yerine bir düğme nesnesine nasıl uygulanabilir ?
storm_m2138

8
Aslında bu yalnızca MDN belgelerinde belirtilenle aynı kökenli URL'ler için geçerlidir. Jenerik bir çözüm geliştirmek istiyorsak, bu büyük bir sınırlamadır
Akshat Gupta

6
Soru açıkça bir bağlantı yerine bir düğme kullanmak istiyor
Quentin

86

HTML:

<button type="submit" onclick="window.open('file.doc')">Download!</button>

8
En iyi ve en temiz çözüm. Ancak burada fazladan Javascript gerekmez. Onclick ile HTML bölümü yeterlidir.
Florian Leitgeb

4
Bir xml dosyası indirmek istersem ne olur?
g07kore

2
Kodun için teşekkürler. Test ettim, IE, Chrome, Firefox'ta çalışabilir.
muthukumar

6
Tarayıcı tarafından PDF gibi kabul edilebilir bir dosyanız varsa, indirme iletişim kutusunu göstermek yerine yeni sekmede açılır.
WindRider

1
window.open tarayıcıda açılır pencere engellemeyi tetikleyebilir ve bu nedenle önerilmez. Aynı tarayıcı penceresindeki konuma gitmekle birlikte window.location = 'path' kullanabilirsiniz.
Elendurwen

68

JQuery ile:

$("#fileRequest").click(function() {
    // // hope the server sets Content-Disposition: attachment!
    window.location = 'file.doc';
});

1
Mükemmel teşekkürler. Çoğu sunucunun Content-Disposition'ı varsayılan olarak 'ek' olarak ayarlayıp ayarlamayacağını biliyor musunuz?
brentonstrine

5
"En" yok. Tamamen bağlıdır. Ayarlanmasına güvenmeyin.
Matt Ball

3
Bu sorun beni balistikleştiriyor ve bu işe yarayan (ve IE tarafından desteklenen) tek seçimdi. Benim gibi herhangi bir n00bs için Content-Disposition'ı ayarlamak için ekleyeceğim, tek yapmanız gereken: <? Php header ('Content-Disposition: attachment; filename = "filename.here"'); ?>
user124384

3
Jquery yok. Dönemi.
Adam Arold

1
Bu doest çalışması bir resim indirmeye çalışıyorsanız, resmi tarayıcıda açar
Dheeraj

34

Eski iş parçacığı ama basit bir js çözümü eksik:

let a = document.createElement('a')
a.href = item.url
a.download = item.url.split('/').pop()
document.body.appendChild(a)
a.click()
document.body.removeChild(a)

24
@NicholasKyriakides Bana bu mücevheri hatırlatıyor: image.ibb.co/dtkUWJ/Selection_002.png
Stefanos Chrs

@BryanLarsen FF'nin hangi sürümü var?
Stefanos Chrs

1
@BryanLarsen Haklısınız, Firefox önce öğeyi gövdeye eklemeden buna izin vermez. Teşekkür ederim, cevabı güncelleyin
Stefanos Chrs

1
İndirme bittikten sonra javascript işlevinin tetiklenmesinin bir yolu var mı? İndirme işlemi başladıktan sonra bir mesaj göstermeye çalışın ve indirme işlemi tamamlandığında mesajı kaldırın.
mohit bansal

1
@mohitbansal (un) neyse ki hayır tarayıcı düzeyinde olduğu gibi
Stefanos Chrs

23

Görünmez iframe ile "hile" ile yapabilirsiniz. Buna "src" ayarladığınızda, tarayıcı aynı "href" değerine sahip bir bağlantıyı tıklatır gibi davranır. Formlu çözümün tersine, örneğin bazı zaman aşımlarından sonra, bazı koşullar karşılandığında indirmeyi etkinleştirmek gibi ek mantık yerleştirmenize olanak tanır.

Ayrıca çok silikadır, kullanırken yeni bir pencere / sekme yanıp sönmez window.open.

HTML:

<iframe id="invisible" style="display:none;"></iframe>

JavaScript:

function download() {
    var iframe = document.getElementById('invisible');
    iframe.src = "file.doc";
}

En azından iframe'i belge.body'ye gerçekten eklerseniz yapar.
yxhuvud

1
Bu, eskiden çalışmasına rağmen şu anda Chrome'da çalışmıyor gibi görünüyor. Acaba Chrome'un farklı sürümlerinde aralıklı olarak durup durmadığını merak ediyorum.
Dobes Vandermeer

61.0.3163.100 (Resmi Derleme) (64 bit) Sürümü ile Chrome'da Çalışıyor
AndrewBenjamin

Firefox v57'deki görüntülerle çalışmaz. Görüntüyü iframe içinde oluşturur.
Antony

15

Bootstrap Sürümü

<a class="btn btn-danger" role="button" href="path_to_file"
   download="proposed_file_name">
  Download
</a>

Bootstrap 4 belgelerinde belgelenmiştir ve Bootstrap 3'te de çalışır.


9
Bunun Bootstrap ile tek ilgisi olan sınıf isimleri, sadece HTML5'in gücü.
Machado

3
Soru açıkça bir bağlantı yerine bir düğme ile nasıl yapılacağını soruyor.
Quentin

2
Eğer bootstrap hakkında hiçbir şey bilmiyorsan, bunun bir düğme olduğunu görürsün.
John Lord

11

Bence aradığınız çözüm bu

<button type="submit" onclick="window.location.href='file.doc'">Download!</button>

Javascript'imin bir CSV dosyası oluşturduğu bir durumdan nefret ediyorum. İndirilecek uzak URL olmadığından aşağıdaki uygulamayı kullanıyorum.

downloadCSV: function(data){
    var MIME_TYPE = "text/csv";

    var blob = new Blob([data], {type: MIME_TYPE});
    window.location.href = window.URL.createObjectURL(blob);
}

404 -> sayfa 404 hata sayfasına dönüşür. diğer location.hrefçözümlerde belirtilenlerle aynı problem .
BananaAcid

9

Ne dersin:

<input type="button" value="Download Now!" onclick="window.location = 'file.doc';">

5
Örneğin, dosyanız bir görüntü ise, tarayıcıda açılacağı için bu çalışmaz.
Juggernaut

Dosya eksikse, tüm sayfayı bir 404 sayfasına yönlendirir
Hugheth

7

İndirme bağlantısını gizleyebilir ve düğmeyi tıklatabilirsiniz.

<button onclick="document.getElementById('link').click()">Download!</button>
<a id="link" href="file.doc" download hidden></a>

Bunun Firefox'ta çalışması için, kaynağın belgeyle aynı alanda olması gerekir. CORS başlıklarını ayarlamak yardımcı olmaz .
Antony

2
Bunu asla yapma
Wannes

@Wannes neden olmasın?
Starwarswii

4

Vanilya JavaScript (jQuery yok) çözümü arıyorsanız ve HTML5 özniteliğini kullanmadan bunu deneyebilirsiniz.

const download = document.getElementById("fileRequest");

download.addEventListener('click', request);

function request() {
    window.location = 'document.docx';
}
.dwnld-cta {
    border-radius: 15px 15px;
    width: 100px;
    line-height: 22px
}
<h1>Download File</h1>
<button id="fileRequest" class="dwnld-cta">Download</button>


1

İndirilecek dosya sayfa yüklendiğinde belirlendiği için nihayet benim için işe yaradı.

Formun eylem özelliğini güncellemek için JS:

function setFormAction() {
    document.getElementById("myDownloadButtonForm").action = //some code to get the filename;
}

Formun eylem özelliğini güncellemek için JS çağrısı:

<body onLoad="setFormAction();">

Gönder düğmesiyle form etiketi:

<form method="get" id="myDownloadButtonForm" action="">
    Click to open document:  
    <button type="submit">Open Document</button>
</form>

Aşağıdaki vermedi DEĞİL çalışır:

<form method="get" id="myDownloadButtonForm" action="javascript:someFunctionToReturnFileName();">

büyük olasılıkla dosya yükleme zamanında varsa, sadece bir şablon motor kullanarak eylemi sunucuda gerçekleştiremezsiniz çünkü? neden js kodu ihtiyacı?
Andrei Epure

1

Formu kullanamıyorsanız, downloadjs ile başka bir yaklaşım da çok uygun. Downloadjs başlık altında blob ve html 5 dosya API'sini kullanır:

{downloadjs (url, dosya adı)}) />

* bu jsx / tepki sözdizimi, ancak saf html'de kullanılabilir


Diğer alanlardaki görüntülerde CORS sorunlarından kaçınmak için img etiketine crossorigin = "anonim" ifadesini şu şekilde yerleştirin: <img src = "image.png" crossorigin = "anonim" />
Jonathan Harris

0

<body>Ve </body>etiketleriniz arasında herhangi bir yere aşağıdaki kodu kullanarak bir düğme yerleştirin:

<button>
    <a href="file.doc" download>Click to Download!</a>
</button>

Bu kesinlikle işe yarar!


1
Chrome için harika bir çözüm
Hayk Aramyan

1
Safari'de de çalışmıyor: W3 Okulları
Alex

2
MS tarayıcılarda çalışmamak oldukça büyük bir sorundur ve Chrome her zaman cevap olmayacaktır.
SudoKid

HTML'deki bir düğmenin içine bağlantı koyamazsınız
Quentin

0

file.doc?foo=bar&jon=doeFormun içine gizli alan eklemek gibi karmaşık bir URL'niz olması durumunda bunu yapmanın başka bir yolu da

<form method="get" action="file.doc">
  <input type="hidden" name="foo" value="bar" />
  <input type="hidden" name="john" value="doe" />
  <button type="submit">Download Now</button>
</form>

tamamlanmamış olan @Cfreak cevabından ilham aldı


0

herhangi bir metin olmadan ancak bağlantı içeren etiket ekleyebilirsiniz. ve kodunuzda olduğu gibi düğmeyi tıklattığınızda, $ ("yourlinkclass") komutunu çalıştırmanız yeterlidir.


-1

indirme özelliği yap

 <a class="btn btn-success btn-sm" href="/file_path/file.type" download>
     <span>download </span>&nbsp;<i class="fa fa-download"></i>
 </a>

2
Cevabınızı seviyorum
George C.

2
Soru açıkça bir bağlantı yerine bir düğme ile nasıl yapılacağını soruyor.
Quentin

-6

Eğer kullanırsanız <a>etiketi, hangi dosyaya açar tamamını url kullanmak unutma - yani:

<a href="http://www.example.com/folder1/file.doc">Download</a>

Burada sorun olduğunu sanmıyorum. Ayrıca, bağlantı dosyayla aynı yoldaysa "mutlak" yol da gerekmez.
Rocket Hazmat

@Rocket - elbette, mutlak yol konusunda haklısınız, ancak doğru yapmak için emin olmanın en iyi yolu budur. Yararlı olup olmadığına karar vermek için OP'ye bırakacağım -
Mark

Soru açıkça bir bağlantı yerine bir düğme ile nasıl yapılacağını soruyor.
Quentin

bu öznitelikte indirme özelliği eksik. İndirme öznitelikleri eklendikten sonra bile alanlar arası için çalışmaz.
s sharif

-6

Benim için bağlantı metni yerine reklam düğmesi gerçekten iyi çalışıyor.

<a href="file.doc"><button>Download!</button></a>

Çoğu kuralda iyi olmayabilir, ancak oldukça iyi görünüyor.


5
Bu yalnızca tarayıcınız .doc dosyalarını desteklemediği için çalışır.
Adrian

HTML'niz geçersiz. <a>elemanlar eleman içeremez <button>.
Quentin

her zaman böyle miydi? Bunu cevapladığınızda bu cevap iki yaşındaydı.
John Lord
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.