154 Stimmen

Einfachste Möglichkeit, ein Download-Fenster zu öffnen, ohne die Seite zu verlassen

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

19voto

alockwood05 Punkte 946

Ich habe nach einer guten Möglichkeit gesucht, Javascript zu verwenden, um den Download einer Datei zu initiieren, genau wie diese Frage vorschlägt. Allerdings waren diese Antworten nicht hilfreich. Ich habe dann einige xbrowser Tests und haben festgestellt, dass ein iframe funktioniert am besten auf allen modernen Browsern IE>8.

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 zur Gestaltung von Inhalten, die zwar 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; 
}

gleich wie .visuallyHidden in html5boilerplate

Ich ziehe dies der Javascript-Methode window.open vor, da die iframe-Methode bei einem defekten Link einfach nichts tut, im Gegensatz zur Weiterleitung zu einer leeren Seite, 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();

9voto

loretoparisi Punkte 14321

HTML5 verwenden Blob Objekt-URL-Datei-API:

/**
 * Save a text as file using HTML <a> temporary element and Blob
 * @see https://stackoverflow.com/questions/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 https://stackoverflow.com/questions/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)

6voto

Bnrdo Punkte 5155

Die Änderung der Position des Fensters kann zu Problemen führen, insbesondere wenn Sie eine dauerhafte Verbindung wie einen Websocket haben. Daher greife ich immer auf die 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();
}

5voto

TaylorMac Punkte 8612

Wenn der Link auf eine gültige Datei-URL verweist, genügt die Zuweisung von window.location.href.

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

Tun Sie Ihre normale event.preventDefault, um das Fenster vom Öffnen zu verhindern, und wenn Sie jQuery verwenden, wird dies funktionieren:

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

3voto

М.Б. Punkte 1200

Nach stundenlangen Versuchen ist die Funktion geboren :) Ich hatte ein Szenario, wo ich Loader in der Zeit anzeigen musste, während die Datei für den Download vorbereitet wird:

Funktioniert 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)
        }
    });

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X