Einfachste Möglichkeit, ein Download-Fenster zu öffnen, ohne von der Seite weg zu navigieren

117

Was ist der beste browserübergreifende Weg, um einen Download-Dialog zu öffnen (nehmen wir an, wir können die Inhaltsdisposition festlegen: Anhang in den Kopfzeilen), ohne von der aktuellen Seite weg zu navigieren oder Popups zu öffnen, was in Internet Explorer (IE) nicht gut funktioniert ) 6.

mkoryak
quelle

Antworten:

105

7 Jahre sind vergangen und ich weiß nicht, ob es für IE6 funktioniert oder nicht, aber dies fordert OpenFileDialog in FF und Chrome auf.

var file_path = 'host/path/file.ext';
var a = document.createElement('A');
a.href = file_path;
a.download = file_path.substr(file_path.lastIndexOf('/') + 1);
document.body.appendChild(a);
a.click();
document.body.removeChild(a);
0x000f
quelle
Zuerst danke für diese Lösung, aber ich habe einen Fehler gefunden, wenn removeChild (a) die Zip entpackt Fehler mit Zip ist defekt, also entfernen Sie diesen Code lösen Sie es
Roy
2
@Manoj Rana - Ich habe auf FF 58.0.2 (64-Bit) überprüft, ob es funktioniert. Es funktioniert bei keinem FF, wenn Sie 2 Zeilen entfernen document.body.appendChild (a); document.body.removeChild (a);
0x000f
1
Damit es auf Edge 16 funktioniert, sollte der Header, von dem die Datei stammt, Content-Type: application/octet-streamund enthalten Content-Disposition: attachment.
Simon
12
Dies funktioniert nicht mehr Entwickler.google.com/web/updates/2018/02/…
Paulius Dragunas
2
@ user1933131 Chrom entfernt nur für Cross-Origin
Brandy23
198

Dieses Javascript ist schön, dass es kein neues Fenster oder Tab öffnet.

window.location.assign(url);
Mozgras
quelle
17
Dies ist dasselbe wie window.location = url; "Immer wenn dem Standortobjekt ein neuer Wert zugewiesen wird, wird ein Dokument unter Verwendung der URL geladen, als ob window.location.assign () mit der geänderten URL aufgerufen worden wäre" - developer.mozilla.org/en-US/docs/ Web / API / window.location
Rob Juurlink
13
Dadurch wird die WebSocket-Verbindung getrennt.
Igorpavlov
4
Ich habe dieselbe Lösung verwendet, aber sie öffnet die Datei auf derselben Registerkarte, anstatt einen Download-Dialog zu öffnen.
Techno Cracker
2
Es ist dasselbe wie bei window.open (url, '_self'), wenn die URL dann zum Herunterladen bestimmt ist.
Experte will
5
Bei der Verwendung von IE11 stellte ich fest, dass JS dadurch gestoppt wurde. Für IE 11 habe ich window.open (url, '_blank') verwendet, wodurch eine andere Registerkarte geöffnet wurde. Diese Registerkarte wurde jedoch geschlossen, als die Datei ausgearbeitet wurde. Es handelte sich um einen Download. Dies hielt den JS am Laufen.
Luke
23

Ich füge dem Download-Link immer ein target = "_ blank" hinzu. Dadurch wird ein neues Fenster geöffnet. Sobald der Benutzer auf Speichern klickt, wird das neue Fenster geschlossen.

jao
quelle
2
Dies ist die beste Antwort. Wenn Sie in Internet Explorer einem herunterzuladenden Link das 'target = "_ blank"' hinzufügen, kann der Browser nicht mehr navigieren (wo "HTML1300: Navigation aufgetreten" gedruckt wird) und die Seite in einem inkonsistenten Zustand belassen.
user64141
23

Fügen Sie dies in den HTML-Kopfabschnitt ein und setzen Sie die urlVariable auf die URL der herunterzuladenden Datei:

<script type="text/javascript">  
function startDownload()  
{  
     var url='http://server/folder/file.ext';    
     window.open(url, 'Download');  
}  
</script>

Dann legen Sie dies in den Körper, der den Download nach 5 Sekunden automatisch startet:

<script type="text/javascript">  
setTimeout('startDownload()', 5000); //starts download after 5 seconds  
</script> 

(Von hier .)

George Claghorn
quelle
2
Das funktioniert nicht, da in IE6 die Datei gespeichert wird, wenn der Benutzer auf "Speichern" klickt, das Popup jedoch geöffnet bleibt. Das ist nicht akzeptabel.
Mkoryak
Dieser Code funktioniert nicht in Safari. Können Sie mir bitte helfen, in Safari gelöst zu werden?
Renish Khunt
17

Ich weiß, dass die Frage gestellt wurde, 7 years and 9 months agoaber viele veröffentlichte Lösungen scheinen nicht zu funktionieren, zum Beispiel die Verwendung einer Funktion, <iframe>die nur mit FireFoxfunktioniert und mit der nicht funktioniert Chrome.

Beste Lösung:

Die beste Lösung zum Öffnen eines Popups zum Herunterladen von Dateien JavaScriptist die Verwendung eines HTMLLink-Elements, ohne dass das Link-Element an dasdocument.body in anderen Antworten angegebene Element angehängt werden muss.

Sie können die folgende Funktion verwenden:

function downloadFile(filePath){
    var link=document.createElement('a');
    link.href = filePath;
    link.download = filePath.substr(filePath.lastIndexOf('/') + 1);
    link.click();
}

In meiner Anwendung verwende ich es folgendermaßen:

downloadFile('report/xls/myCustomReport.xlsx');

Arbeitsdemo:

Hinweis:

  • Sie müssen das link.downloadAttribut verwenden, damit der Browser die Datei nicht in einem neuen Tab öffnet und das Download-Popup auslöst.
  • Dies wurde mit verschiedenen Dateitypen (docx, xlsx, png, pdf, ...) getestet.
cнŝdk
quelle
Was wäre der beste Weg, um ein Lade-GIF anzuzeigen, bis die Datei heruntergeladen wurde?
Ctrl_Alt_Defeat
1
@Ctrl_Alt_Defeat Nun , in diesem Fall wird es nicht einfach sein , den Download - Prozess zu verfolgen, sondern ein Trick kann diese GIF - Animation auf das zeigen, linkklicken und versteckt es nach einem Timeout, diesen Code verwenden: link.onclick = function() { document.body.innerText = "The file is being downloaded ..."; setTimeout(function() { document.body.innerText = ""; }, 2000); }Sie können es Arbeit sehen in diesem Geige , aber denken Sie daran, dass dies keine empfohlene Methode ist. Es wäre besser, wenn wir es verwenden würden Ajax.
cнŝdk
1
Es funktioniert nicht in Firefox. Wie in Firefox herunterladen?
Manoj Rana
@ManojRana für Firefox können Sie ein verwenden iframesehen Sie diese Antwort .
cнŝdk
2
Diese Lösung funktioniert in Chrome, Safari und Firefox für mich :)
Ariebear
15

Ich habe nach einer guten Möglichkeit gesucht, mit Javascript den Download einer Datei zu starten, genau wie diese Frage nahelegt. Diese Antworten waren jedoch nicht hilfreich. Ich habe dann einige xbrowser-Tests durchgeführt und festgestellt, dass ein iframe auf allen modernen Browsern IE> 8 am besten funktioniert.

downloadUrl = "http://example.com/download/file.zip";
var downloadFrame = document.createElement("iframe"); 
downloadFrame.setAttribute('src',downloadUrl);
downloadFrame.setAttribute('class',"screenReaderText"); 
document.body.appendChild(downloadFrame); 

class="screenReaderText" ist meine Klasse, um Inhalte zu stylen, die vorhanden, aber nicht sichtbar sind.

CSS:

.screenReaderText { 
  border: 0; 
  clip: rect(0 0 0 0); 
  height: 1px; 
  margin: -1px; 
  overflow: hidden; 
  padding: 0; 
  position: absolute; 
  width: 1px; 
}

das gleiche wie .visuallyHidden in html5boilerplate

Ich ziehe dies der Javascript-window.open-Methode vor, da die iframe-Methode bei einer Unterbrechung des Links einfach nichts unternimmt, anstatt auf eine leere Seite umzuleiten, die besagt, dass die Datei nicht geöffnet werden konnte.

window.open(downloadUrl, 'download_window', 'toolbar=0,location=no,directories=0,status=0,scrollbars=0,resizeable=0,width=1,height=1,top=0,left=0');
window.focus();
alockwood05
quelle
6

Verwenden der HTML5- Blob- Objekt-URL-Datei-API:

/**
 * Save a text as file using HTML <a> temporary element and Blob
 * @see /programming/49988202/macos-webview-download-a-html5-blob-file
 * @param fileName String
 * @param fileContents String JSON String
 * @author Loreto Parisi
*/
var saveBlobAsFile = function(fileName,fileContents) {
    if(typeof(Blob)!='undefined') { // using Blob
        var textFileAsBlob = new Blob([fileContents], { type: 'text/plain' });
        var downloadLink = document.createElement("a");
        downloadLink.download = fileName;
        if (window.webkitURL != null) {
            downloadLink.href = window.webkitURL.createObjectURL(textFileAsBlob);
        }
        else {
            downloadLink.href = window.URL.createObjectURL(textFileAsBlob);
            downloadLink.onclick = document.body.removeChild(event.target);
            downloadLink.style.display = "none";
            document.body.appendChild(downloadLink);
        }
        downloadLink.click();
    } else {
        var pp = document.createElement('a');
        pp.setAttribute('href', 'data:text/plain;charset=utf-8,' + encodeURIComponent(fileContents));
        pp.setAttribute('download', fileName);
        pp.onclick = document.body.removeChild(event.target);
        pp.click();
    }
}//saveBlobAsFile

/**
 * Save a text as file using HTML <a> temporary element and Blob
 * @see /programming/49988202/macos-webview-download-a-html5-blob-file
 * @param fileName String
 * @param fileContents String JSON String
 * @author Loreto Parisi
 */
var saveBlobAsFile = function(fileName, fileContents) {
  if (typeof(Blob) != 'undefined') { // using Blob
    var textFileAsBlob = new Blob([fileContents], {
      type: 'text/plain'
    });
    var downloadLink = document.createElement("a");
    downloadLink.download = fileName;
    if (window.webkitURL != null) {
      downloadLink.href = window.webkitURL.createObjectURL(textFileAsBlob);
    } else {
      downloadLink.href = window.URL.createObjectURL(textFileAsBlob);
      downloadLink.onclick = document.body.removeChild(event.target);
      downloadLink.style.display = "none";
      document.body.appendChild(downloadLink);
    }
    downloadLink.click();
  } else {
    var pp = document.createElement('a');
    pp.setAttribute('href', 'data:text/plain;charset=utf-8,' + encodeURIComponent(fileContents));
    pp.setAttribute('download', fileName);
    pp.onclick = document.body.removeChild(event.target);
    pp.click();
  }
} //saveBlobAsFile

var jsonObject = {
  "name": "John",
  "age": 31,
  "city": "New York"
};
var fileContents = JSON.stringify(jsonObject, null, 2);
var fileName = "data.json";

saveBlobAsFile(fileName, fileContents)

loretoparisi
quelle
2
Ich denke, das ist der beste Weg, es zu tun !!
Kushal MK
1
Es ist auch eine gute Praxis, aufzurufen URL.revokeObjectURL(url), wenn die Datei nicht mehr benötigt wird, um den Speicher
freizugeben
5

Das Ändern des Speicherorts des Fensters kann zu Problemen führen, insbesondere wenn Sie eine dauerhafte Verbindung wie Websocket haben. Deshalb greife ich immer auf eine gute alte Iframe-Lösung zurück.

HTML

<input type="button" onclick="downloadButtonClicked()" value="Download"/>
...
...
...
<iframe style="display:none;" name="hiddenIframe" id="hiddenIframe"></iframe>

Javascript

function downloadButtonClicked() {
    // Simulate a link click
    var url = 'your_download_url_here';
    var elem = document.createElement('a');
    elem.href = url;
    elem.target = 'hiddenIframe';
    elem.click();
}
Bnrdo
quelle
5

Wenn der Link zu einer gültigen Datei-URL führt, funktioniert es einfach, window.location.href zuzuweisen.

Manchmal ist der Link jedoch ungültig und ein iFrame ist erforderlich.

Führen Sie Ihr normales event.preventDefault aus, um das Öffnen des Fensters zu verhindern. Wenn Sie jQuery verwenden, funktioniert dies wie folgt:

$('<iframe>').attr('src', downloadThing.attr('href')).appendTo('body').on("load", function() {
   $(this).remove();
});
TaylorMac
quelle
2

Nach stundenlangem Versuch ist die Funktion geboren :) Ich hatte ein Szenario, in dem ich den Loader rechtzeitig anzeigen musste, während sich die Datei auf den Download vorbereitet:

Arbeiten in Chrome, Safari und Firefox

function ajaxDownload(url, filename = 'file', method = 'get', data = {}, callbackSuccess = () => {}, callbackFail = () => {}) {
    $.ajax({
        url: url,
        method: 'GET',
        xhrFields: {
            responseType: 'blob'
        },
        success: function (data) {
            // create link element
            let a = document.createElement('a'), 
                url = window.URL.createObjectURL(data);

            // initialize 
            a.href = url;
            a.download = filename;

            // append element to the body, 
            // a must, due to Firefox
            document.body.appendChild(a);

            // trigger download
            a.click();

            // delay a bit deletion of the element
            setTimeout(function(){
                window.URL.revokeObjectURL(url);
                document.body.removeChild(a);
            }, 100);

            // invoke callback if any 
            callbackSuccess(data);
        },
        error: function (err) {
            // invoke fail callback if any
            callbackFail(err)
        }
    });
М.Б.
quelle
0

Wie wäre es mit:

<meta http-equiv="refresh" content="5;url=http://site.com/file.ext">

Diese Methode funktioniert in allen Browsern (glaube ich) und lässt Sie eine Nachricht wie folgt eingeben: "Wenn der Download nicht in fünf Sekunden startet, klicken Sie hier."

Wenn Sie es brauchen, um mit Javascript zu sein .. na ja ...

document.write('<meta http-equiv="refresh" content="5;url=http://site.com/file.ext">');

Grüße


quelle
0

Ein kleiner / versteckter Iframe kann für diesen Zweck funktionieren.

Auf diese Weise müssen Sie sich keine Sorgen mehr über das Schließen des Popups machen.

Simon
quelle