2016-08-02 8 views
9

Zgodnie z caniuse atrybut download elementu <a> jest obsługiwany pod numerem Microsoft Edge build 10547+, ale not IE or Safari.Jak pobrać plik bez użycia elementu <a> z atrybutem pobierania lub serwerem?

Jak pobrać obiekt pliku bez użycia elementu <a> z zestawem atrybutów download lub serwerem?

+2

Można sprawdzić moją odpowiedź tutaj: https://stackoverflow.com/questions/38524320/download-pdf -file-from-ajax-response/38552959 # 38552959 Daje dokładnie to, czego szukasz. – Dekel

+0

@Dekel Zobacz kryteria w OP, '.responseType' nie został zdefiniowany w tym momencie w rozwoju przeglądarki. – guest271314

+0

szukasz rozwiązania na rok 2016 kompatybilny z przeglądarką lub 2017? :) – Dekel

Odpowiedz

10

Istnieje kilka sposobów uruchamiania pobierania. Oto kilka z nich:

skorzystać z formularza:

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

użycie javascript:

<button type="submit" onclick="window.open('mydoc.doc')">Download</button> 
+0

co jeśli użytkownik ma wtyczkę do przeglądarki który otwiera mydoc.doc? to w jaki sposób zostanie pobrany? – Star

+0

Użytkownik może wybrać zapisywanie treści, które widzi za pomocą wtyczki przeglądarki. Jednak nie można wymusić pobierania z front-endu. Zobacz: https://stackoverflow.com/questions/8613725/how-can-i-force-download-with-html-and-or-javascript/8613899#8613899 –

1

Można użyć data URIdata:[<mediatype>][;base64],<data> reprezentacji pliku albo tworzone ręcznie lub wykorzystując FileReader(), .readAsDataURL() z MIME typu ustawiony na application/octet-stream, encodeURIComponent(), window.open()

<script> 
    var file = "data:application/octet-stream," 
      + encodeURIComponent("<!DOCTYPE html>" 
      + "<html><body>" 
      + "<div>abc</div>" 
      + "</body></html>"); 
    var saveFile = window.open(file, "_self");  
</script> 

<script> 
    var blob = new Blob(["abc"], {type:"text/plain"}); 
    var reader = new FileReader(); 
    reader.addEventListener("load", function(e) { 
    // replace existing `MIME` type with `application/octet-stream` 
    var file = "data:application/octet-stream;" 
       + e.target.result.split(/;/)[1]; 
    var saveFile = window.open(file, "_self"); 
    }); 
    reader.readAsDataURL(blob) 
</script> 

plnkr http://plnkr.co/edit/IS1OC0laRwL3BuuF9zay?p=preview

1

Chociaż popieram @ odpowiedź LeoFarmer za, chciałbym zaoferować dwa "hackable" podejścia:

  1. Jeśli plik jest bardzo mała , możesz użyć a z href='data:[<mediatype>][;base64],<data>'.

    To może pozwolić na dodanie kompozycji zawartości w mediatype, emulując nagłówek HTTP. Ten hack nie jest tak przenośny, jak można mieć nadzieję.

  2. Na małych i średnich plikach możliwe jest pobranie pliku przy użyciu technologii AJAX, a następnie use the Javascript File API to prompt for file saving (interfejs API nie obsługuje zapisywania, ale można łatwo przekonwertować dane na adres URL danych).

    Jeśli chcesz uniknąć interfejsu API plików JavaScript, możesz spróbować emulować kliknięcie kotwicy jako suggested here.

Ponownie, jak podkreślił Leo Farmer, rozwiązania te nie mogą obiecać, że przeglądarka nie będzie otworzyć plik w nowej karcie zamiast zapisywania go na dysku, ale myślę, że to na pewno powiedzieć, że wszyscy użytkownicy będą w stanie zgrabnie zniszczyć skrót klawiaturowy cmd+S lub ctrl+S :-)

1

Możesz to zrobić, używając zarówno atrybutu pobierania, jak i jquery. atrybut pobierania nie obsługuje w ie i safari/ios. Więc można użyć jQuery to zrobić

$('.download').click(function(e) { 
    e.preventDefault(); //stop the browser from following 
    window.location.href = 'uploads/file.doc'; 
}); 

<a href="no-script.html" class="download">Download</a> 
1

Zastosowanie FileSaver.js

Obsługuje wszystkie powszechnie używanych przeglądarek.

Właśnie to:

<script type="text/javascript" src="FileSaver.min.js"></script> 

i używać go lubię:

var file = new File(["Hello, world!"], "hello world.txt", {type: "text/plain;charset=utf-8"}); 
saveAs(file); 

Uwaga: Aby pracować również w Safari < 6, Opera < 15 i Firefox < 20 musisz dołączyć Blob.js jako zależność.

+0

Jest Konstruktor 'Plik' dostępny w przeglądarkach wymienionych na ostatnie zdanie odpowiedzi? – guest271314

+0

Nie, nie robią tego. (http://caniuse.com/#search=File) Ale spójrz na dokumentację FileSaver.js, są inne sposoby jej zapisania. Mam nadzieję, że okaże się to pomocne. :) – padr

-1

Jeśli używasz serwera, a następnie wykonaj mechanizm składania formularza, aby wyrenderować stronę. W MVC możemy skorzystać z poniższego kodu

html

@using (Html.BeginForm("GetAttachment", "User", FormMethod.Post)) 
       { 

        <button type="submit">Download</button> 
       } 

MVC Controller

public ActionResult GetAttachment() 
{ 
    string filename = "File.pdf"; 
string filepath = AppDomain.CurrentDomain.BaseDirectory + "/Path/To/File/" + filename; 
byte[] filedata = System.IO.File.ReadAllBytes(filepath); 
string contentType = MimeMapping.GetMimeMapping(filepath); 

var cd = new System.Net.Mime.ContentDisposition 
{ 
    FileName = filename, 
    Inline = true, 
}; 

Response.AppendHeader("Content-Disposition", cd.ToString()); 

return File(filedata, contentType); 
} 
+0

przy użyciu formularza przesyłamy dane do serwera i serwer zwraca plik. –

+1

''

'' 'nie trzeba przekazywać na serwer. Wymaganie pytania polega na tym, aby nie używać serwera – guest271314