Jak uruchomić pobieranie pliku po kliknięciu przycisku HTML lub JavaScript

434

To szalone, ale nie wiem, jak to zrobić, a ze względu na to, jak popularne są te słowa, trudno jest znaleźć to, czego potrzebuję w wyszukiwarkach. Myślę, że odpowiedź na to pytanie powinna być łatwa.

Chcę pobrać prosty plik, który zrobiłby to samo, co to:

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

Ale chcę użyć przycisku HTML, np. Jednego z tych:

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

Podobnie, czy można uruchomić proste pobieranie przez JavaScript?

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

Zdecydowanie nie szukam sposobu na stworzenie kotwicy, która wygląda jak przycisk, nie używa skryptów zaplecza ani nie zadziera z nagłówkami serwerów lub typami MIME.

brentonstrine
źródło
15
Dzięki tobie „jak uruchomić pobieranie pliku w javascript” dałoby odpowiedzi znacznie szybciej dla każdego przyszłego wyszukiwarki.
Danubian Sailor

Odpowiedzi:

278

Dla przycisku możesz zrobić

<form method="get" action="file.doc">
   <button type="submit">Download!</button>
</form>
Cfreak
źródło
Możesz zapisać znacznik formularza i po prostu dodać kliknięcie do znacznika przycisku.
Florian Leitgeb
12
nie działa jako wyzwalacz, wystarczy przekierować na adres URL jako tag „a”.
fdrv,
7
Działa to lepiej: <a href="path_to_file" download="proposed_file_name"> Pobierz </a>
kscius
11
@kscius nawet dzisiaj atrybut pobierania nie jest obsługiwany w IE 11 (jest teraz obsługiwany w Edge) i nie jest obsługiwany w Safari. W 2012 roku, kiedy odpowiedź została pierwotnie opublikowana, nie była obsługiwana w żadnej większej przeglądarce.
Cfreak,
1
Jaka jest różnica między posiadaniem kotwicy ze stylizacją guzika a formą z guzikiem?
Andrei Epure
444

Możesz uruchomić pobieranie za pomocą downloadatrybutu HTML5 .

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

Gdzie:

  • path_to_fileto ścieżka, która przekształca się w adres URL tego samego źródła . Oznacza to, że strona i plik muszą mieć tę samą domenę, subdomenę, protokół (HTTP vs. HTTPS) i port (jeśli określono). Wyjątkami są blob:i data:(które zawsze działają) i file:(które nigdy nie działają).
  • proposed_file_nameto nazwa pliku do zapisania. Jeśli jest puste, przeglądarka domyślnie przyjmuje nazwę pliku.

Dokumentacja: MDN , HTML Standard podczas pobierania , HTML Standard włączonydownload , CanIUse

Joe Pigott
źródło
37
Nie działa z Safari i niektórymi wersjami IE
Mohamed Hussain
4
Użycie kombinacji downloadi target="_blank"wydaje się wystarczające do pokrycia większości przypadków użycia. Przeglądarki, które to rozumieją, downloadtraktują to jako pobranie, w przeciwnym razie zostanie otwarte w nowej karcie.
MK10
10
Jak można to zastosować do obiektu przycisku zamiast tylko znacznika ?
storm_m2138
8
W rzeczywistości działa to tylko w przypadku adresów URL tego samego pochodzenia, jak wspomniano w dokumentach MDN. To ogromne ograniczenie, jeśli chcemy opracować ogólne rozwiązanie
Akshat Gupta
6
Pytanie wyraźnie wymaga użycia przycisku zamiast łącza
Quentin
86

HTML:

<button type="submit" onclick="window.open('file.doc')">Download!</button>
śpioch
źródło
8
Najlepsze i najbardziej czyste rozwiązanie. Ale nie potrzebujesz tutaj dodatkowego Javascript. Wystarczy część HTML z kliknięciem onclick.
Florian Leitgeb
4
Co jeśli chcę pobrać plik XML?
g07kore
2
Dziękuję za Twój kod. Przetestowałem, może działać w IE, Chrome, Firefox.
muthukumar
6
Jeśli masz plik akceptowany przez przeglądarkę, taki jak PDF, zostanie on otwarty w nowej karcie, aby wyświetlić okno dialogowe pobierania.
WindRider
1
Window.open może powodować blokowanie wyskakujących okienek w przeglądarce i dlatego nie jest zalecane. Możesz użyć window.location = 'path', chociaż trafiłoby to do lokalizacji w tym samym oknie przeglądarki.
Elendurwen,
68

Z jQuery:

$("#fileRequest").click(function() {
    // // hope the server sets Content-Disposition: attachment!
    window.location = 'file.doc';
});
Matt Ball
źródło
1
Perfekcyjnie, dzięki. Czy zdarza ci się wiedzieć, czy większość serwerów domyślnie ustawia Dyspozycyjność na „załącznik”?
brentonstrine
5
Nie ma „większości”. To całkowicie zależy. Nie polegaj na tym, że jest ustawiony.
Matt Ball
3
Ten problem doprowadził mnie do balistyki i była to jedyna opcja, która zadziałała (i jest obsługiwana przez IE). Dodam dla każdego n00bs takiego jak ja, że ​​aby ustawić Content-Disposition, wszystko co musisz zrobić to: <? Php header ('Content-Disposition: załącznik; filename = "nazwa_pliku.here"'); ?>
user124384,
3
Bez jquery. Kropka.
Adam Arold,
1
Ta czynność działa, jeśli próbujesz pobrać obraz, otworzyłby on obraz w przeglądarce
Dheeraj
34

Stary wątek, ale brakuje w nim prostego rozwiązania js:

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)
Stefanos Chrs
źródło
24
@NicholasKyriakides Przypomina mi ten klejnot: image.ibb.co/dtkUWJ/Selection_002.png
Stefanos Chrs
@BryanLarsen jaka wersja FF?
Stefanos Chrs
1
@BryanLarsen Masz rację, Firefox nie pozwala na to, nie dodając najpierw elementu do treści. Dziękuję, aktualizuję odpowiedź
Stefanos Chrs
1
Czy istnieje sposób uruchomienia funkcji javascript po zakończeniu pobierania? Po prostu próbuję wyświetlić wiadomość po rozpoczęciu pobierania i usunąć wiadomość po zakończeniu pobierania.
mohit bansal
1
@mohitbansal (un) na szczęście nie, ponieważ jest na poziomie przeglądarki
Stefanos Chrs
23

Możesz to zrobić za pomocą „sztuczki” z niewidocznym iframe. Po ustawieniu na niego opcji „src” przeglądarka reaguje tak, jakbyś kliknął link z tym samym „href”. W przeciwieństwie do rozwiązania z formularzem, umożliwia osadzenie dodatkowej logiki, na przykład aktywowanie pobierania po upływie limitu czasu, gdy spełnione są określone warunki itp.

Jest również bardzo cichy, nie ma migającego nowego okna / karty, jak podczas korzystania window.open.

HTML:

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

JavaScript:

function download() {
    var iframe = document.getElementById('invisible');
    iframe.src = "file.doc";
}
Żeglarz naddunajski
źródło
Dzieje się tak, przynajmniej jeśli faktycznie zatwierdzasz ramkę iframe do document.body.
yxhuvud
1
Wydaje się, że nie działa to teraz w Chrome, chociaż kiedyś działało. Zastanawiam się, czy to w jakiś sposób przestaje działać w różnych wersjach Chrome.
Dobes Vandermeer
Pracuje w Chrome od wersji 61.0.3163.100 (Dziennik budowy) (64-bit)
AndrewBenjamin
Nie działa z obrazami w przeglądarce Firefox v57. Po prostu renderuje obraz w ramce iframe.
Antony
15

Wersja Bootstrap

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

Udokumentowane w dokumentach Bootstrap 4 i działa również w Bootstrap 3.

Wsparcie CFP
źródło
9
Jedyne, co ma to wspólnego z Bootstrap, to nazwy klas, to tylko moc HTML5.
Machado
3
Pytanie wyraźnie pyta, jak to zrobić za pomocą przycisku zamiast łącza.
Quentin
2
jeśli cokolwiek wiesz o bootstrapie, zobaczysz, że JEST to przycisk.
John Lord
11

Myślę, że to było rozwiązanie, którego szukałeś

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

Mam przypadek, w którym mój Javascript wygenerował plik CSV. Ponieważ nie ma zdalnego adresu URL do pobrania, używam następującej implementacji.

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

    var blob = new Blob([data], {type: MIME_TYPE});
    window.location.href = window.URL.createObjectURL(blob);
}
Delconis
źródło
na stronie 404 -> zmiana strony na stronę błędu 404. ten sam problem, co stwierdzony w innych location.hrefrozwiązaniach.
BananaAcid
9

Co powiesz na:

<input type="button" value="Download Now!" onclick="window.location = 'file.doc';">
olli
źródło
5
To nie działa, jeśli na przykład plik jest obrazem, ponieważ zostałby po prostu otwarty w przeglądarce.
Juggernaut
Kolejny problem występuje, gdy brak pliku powoduje przejście całej strony do strony 404
Hugheth,
7

Możesz ukryć link do pobrania i kliknąć go przyciskiem.

<button onclick="document.getElementById('link').click()">Download!</button>
<a id="link" href="file.doc" download hidden></a>
Starwarswii
źródło
Aby działało to w przeglądarce Firefox, zasób musi znajdować się w tej samej domenie co dokument. Ustawienie nagłówków CORS nie pomaga.
Antony
2
Nigdy tego nie rób
Wannes,
@Wannes, dlaczego nie?
Starwarswii
4

Jeśli szukasz waniliowego rozwiązania JavaScript (bez jQuery) i bez użycia atrybutu HTML5 możesz spróbować tego.

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>

David Willhite
źródło
1

To w końcu działało dla mnie, ponieważ plik do pobrania został określony podczas ładowania strony.

JS, aby zaktualizować atrybut akcji formularza:

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

Wywołanie JS w celu zaktualizowania atrybutu akcji formularza:

<body onLoad="setFormAction();">

Tag formularza z przyciskiem Prześlij:

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

Następujące NIE działało:

<form method="get" id="myDownloadButtonForm" action="javascript:someFunctionToReturnFileName();">
slayernoah
źródło
prawdopodobnie dlatego, że jeśli masz plik w czasie ładowania, czy nie możesz po prostu renderować akcji na serwerze przy użyciu silnika szablonów? dlaczego potrzeba kodu js?
Andrei Epure
1

Jeśli nie możesz użyć formularza, inne podejście do downloadjs pasuje dobrze. Pliki do pobrania używają interfejsu API obiektów blob i HTML 5:

{downloadjs (adres URL, nazwa pliku)}) />

* Jest to składnia jsx / reag, ale może być używana w czystym formacie HTML

Gleb Dolzikov
źródło
Aby uniknąć problemów z CORS dla obrazów w innych domenach, umieść crossorigin = "anonimowy" w znaczniku img, tak jak to: <img src = "image.png" crossorigin = "anonimowy" />
Jonathan Harris
0

W dowolnym miejscu między tagiem <body>a </body>tagiem umieść przycisk, używając poniższego kodu:

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

To na pewno zadziała!

Ronaldo
źródło
1
W przypadku Chrome jest to świetne rozwiązanie
Hayk Aramyan
1
Nie działa również w Safari: W3 Schools
Alex
2
Brak działania w przeglądarkach MS jest dość dużym problemem, a Chrome nie zawsze będzie odpowiedzią.
SudoKid
W HTML nie można umieścić linku w przycisku
Quentin
0

Innym sposobem postępowania w przypadku złożonego adresu URL, takiego jak file.doc?foo=bar&jon=doedodanie ukrytego pola w formularzu

<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>

inspirowane odpowiedzią @Cfreak, która nie jest kompletna

Bellash
źródło
0

możesz dodać tag bez tekstu, ale z linkiem. a kiedy klikniesz przycisk tak, jak w kodzie, po prostu uruchom funkcję $ („twoja klasa połączeń”). click ().

ThisisFish
źródło
-1

pobierz atrybut, zrób to

 <a class="btn btn-success btn-sm" href="/file_path/file.type" download>
     <span>download </span>&nbsp;<i class="fa fa-download"></i>
 </a>
Rohallah Hatami
źródło
2
Podoba mi się twoja odpowiedź
George C.
2
Pytanie wyraźnie pyta, jak to zrobić za pomocą przycisku zamiast łącza.
Quentin
-6

Jeśli używasz <a>znacznika, nie zapomnij użyć całego adresu URL, który prowadzi do pliku - tj .:

<a href="http://www.example.com/folder1/file.doc">Download</a>
znak
źródło
Nie sądzę, że tu jest problem. Również ścieżka „bezwzględna” nie jest potrzebna, jeśli link znajduje się w tej samej ścieżce co plik.
Rocket Hazmat
@Rocket - oczywiście masz rację co do ścieżki bezwzględnej, jednak jest to najlepszy sposób, aby upewnić się, że jest dobrze. Zostawię OP, aby zdecydował, czy był pomocny -
Mark
Pytanie wyraźnie pyta, jak to zrobić za pomocą przycisku zamiast łącza.
Quentin
w tym rozwiązaniu brakuje atrybutu pobierania. Nawet po dodaniu atrybutów pobierania nie będzie działać w wielu domenach.
s sharif
-6

Dla mnie przycisk dodawania zamiast tekstu kotwicy działa naprawdę dobrze.

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

Może nie być w porządku według większości zasad, ale wygląda całkiem dobrze.

Brana
źródło
5
Działa to tylko dlatego, że twoja przeglądarka nie obsługuje plików .doc.
Projekt Adrian
Twój kod HTML jest nieprawidłowy. <a>elementy nie mogą zawierać <button>elementów.
Quentin
czy zawsze tak było? Ta odpowiedź miała dwa lata, kiedy to skomentowałeś.
John Lord