Sayfadan ayrılmadan bir indirme penceresi açmanın en kolay yolu


119

Bir indirme iletişim kutusunu açmanın en iyi çapraz tarayıcı yolu nedir (varsayalım ki, mevcut sayfadan ayrılmadan veya Internet Explorer'da (IE) iyi çalışmayan açılır pencereleri açmadan içerik ayırma: başlıklarda ek ayarlayabileceğimizi varsayalım. ) 6.

Yanıtlar:


107

7 yıl geçti ve IE6 için çalışıp çalışmadığını bilmiyorum, ancak bu FF ve Chrome'da OpenFileDialog'u soruyor.

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

Öncelikle bu çözüm için teşekkür ederim, ancak removeChild (a) zip dosyası zip ile birlikte fermuarını açacaksa bir hata buldum, bu yüzden bu kodu kaldırın çöz
Roy

2
@Manoj Rana - FF 58.0.2 (64-bit) üzerinde çalıştığını kontrol ettim. 2 satır document.body.appendChild (a) ' yı kaldırırsanız hiçbir FF üzerinde çalışmaz ; document.body.removeChild (a) '
0x000f

1
Dosya giriyor, gerektiği içeriyor gelen o Kenardan 16 başlık üzerinde çalışmasını sağlamak için Content-Type: application/octet-streamve Content-Disposition: attachment.
Simon


2
@ user1933131 krom yalnızca çapraz kaynak için kaldırılır
Brandy23

202

Bu javascript, yeni bir pencere veya sekme açmaması güzel.

window.location.assign(url);

18
Bu, window.location = url ile aynıdır; "Konum nesnesine yeni bir değer atandığında, bir belge, değiştirilmiş URL ile window.location.assign () çağrılmış gibi URL kullanılarak yüklenecektir" - developer.mozilla.org/en-US/docs/ Web / API / window.location
Rob Juurlink

13
Bu, WebSocket bağlantısının kesilmesine neden olur.
igorpavlov

4
Aynı çözümü kullandım ancak bir indirme iletişim kutusu açmak yerine dosyayı aynı sekmede açıyor.
Techno Cracker

2
url indirme sayfası içinse window.open (url, '_self') ile aynıdır.
Uzman

5
IE11'i kullanırken bunun JS'nin durmasına neden olduğunu gördüm. Bu yüzden IE 11 için başka bir sekme açan window.open (url, '_blank') kullandım, ancak bu sekme dosya çalıştığında kapandı bir indirmeydi. Bu, JS'nin çalışmasını sağladı.
Luke

23

İndirme bağlantısına her zaman bir target = "_ blank" eklerim. Bu yeni bir pencere açacaktır, ancak kullanıcı kaydet düğmesini tıkladığında yeni pencere kapanır.


2
Bu en iyi cevap. Internet Explorer'da, indirilecek bir bağlantıya 'target = "_ blank"' ifadesinin eklenmesi, tarayıcının başka yere gitmesini durdurur (burada "HTML1300: Gezinme oluştu" yazdırılır) ve böylece sayfayı tutarsız bir durumda bırakabilir.
user64141

23

urlVar olanı indirilecek dosyanın URL'sine ayarlayarak bunu HTML head bölümüne yerleştirin :

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

Ardından bunu 5 saniye sonra otomatik olarak indirmeye başlayacak gövdeye koyun:

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

(Gönderen burada .)


2
bu çalışmaz, çünkü IE6'da, kullanıcı "kaydet" i tıklarsa dosya kaydedilir, ancak açılır pencere açık kalır. Bu kabul edilemez.
mkoryak

bu kod safaride çalışmıyor, safaride çözmeme yardım eder misiniz lütfen.
Renish Khunt

17

Sorunun sorulduğunu biliyorum, 7 years and 9 months agoancak gönderilen çözümlerin çoğu işe yaramıyor, örneğin bir <iframe>çalışmayı yalnızca ile kullanmak FireFoxve çalışmamak gibi Chrome.

En iyi çözüm:

Bir dosya indirme açılır penceresini açmak için en iyi çalışma çözümü , bağlantı öğesini diğer yanıtlarda belirtildiği gibi eklemeye gerek kalmadanJavaScript bir HTMLbağlantı öğesi kullanmaktır .document.body

Aşağıdaki işlevi kullanabilirsiniz:

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

Uygulamamda şu şekilde kullanıyorum:

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

Çalışma Demosu:

Not:

  • link.downloadTarayıcının dosyayı yeni bir sekmede açmaması ve indirme açılır penceresini çalıştırması için özelliği kullanmanız gerekir .
  • Bu, çeşitli dosya türleriyle (docx, xlsx, png, pdf, ...) test edilmiştir.

Dosya indirilene kadar bir yükleme gifini görüntülemenin en iyi yolu nedir?
Ctrl_Alt_Defeat

1
@Ctrl_Alt_Defeat Eh bu durumda indirme işlemini izlemek için kolay olmayacak, ama bir hile bu gif animasyonu göstermek için olabilir linktıklama ve bu kodu kullanarak, bir zaman aşımından sonra gizlemek: link.onclick = function() { document.body.innerText = "The file is being downloaded ..."; setTimeout(function() { document.body.innerText = ""; }, 2000); }, çalışıp çalışmadıklarını görebilirsiniz içinde bu keman , ancak bunu yapmanın önerilen bir yolu olmadığını unutmayın, kullansaydık daha iyi halledilirdi Ajax.
cнŝdk

1
firefox'ta çalışmıyor. firefox'ta nasıl indirilir?
Manoj Rana

@ManojRana firefox iframeiçin bu cevabı görmek için bir kullanabilirsiniz .
cнŝdk

2
Bu çözüm benim için Chrome, Safari ve Firefox'ta çalışıyor :)
ariebear

15

Bu sorunun önerdiği gibi, bir dosyanın indirilmesini başlatmak için javascript kullanmanın iyi bir yolunu arıyordum. Ancak bu cevaplar yardımcı olmadı. Daha sonra bazı xbrowser testleri yaptım ve bir iframe'in tüm modern tarayıcılarda IE> 8 en iyi şekilde çalıştığını buldum.

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" benim sınıfım var olan ancak görüntülenemeyen içeriği biçimlendiriyor

css:

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

html5boilerplate içindeki .visuallyHidden ile aynı

Bunu javascript window.open yöntemine tercih ederim, çünkü bağlantı bozulmuşsa, iframe yöntemi, dosyanın açılamadığını söyleyen boş bir sayfaya yönlendirmenin aksine hiçbir şey yapmaz.

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();

6

HTML5 Blob Nesne-URL Dosyası API'sini Kullanma :

/**
 * 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)


2
Bunu yapmanın en iyi yolu olduğunu hissediyorum !!
Kushal MK

1
URL.revokeObjectURL(url)Belleği boşaltmak için dosyaya artık ihtiyaç kalmadığında aramak da iyi bir uygulamadır
SleepWalker

5

Pencerenin konumunu değiştirmek, özellikle websocket gibi kalıcı bir bağlantınız olduğunda bazı sorunlara neden olabilir. Bu yüzden her zaman eski güzel iframe çözümüne başvururum.

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

5

Bağlantı geçerli bir dosya url'sine ise, basitçe window.location.href atamak işe yarayacaktır.

Ancak bazen bağlantı geçerli değildir ve bir iFrame gereklidir.

Pencerenin açılmasını önlemek için normal event.preventDefault'unuzu yapın ve jQuery kullanıyorsanız, bu çalışacaktır:

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

2

Saatler süren denemelerden sonra fonksiyon doğdu :) Dosya indirilmeye hazırlanırken yükleyiciyi zamanında görüntülemem gereken bir senaryom vardı:

Chrome, Safari ve Firefox'ta çalışmak

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

0

Peki ya:

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

Bu yol tüm tarayıcılarda çalışır (sanırım) ve şöyle bir mesaj koymanıza izin verir: "İndirme beş saniye içinde başlamazsa, burayı tıklayın."

Javascript ile olması gerekiyorsa .. peki ...

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

Saygılarımızla


0

Küçük / gizli bir iframe bu amaç için çalışabilir.

Bu şekilde açılır pencereyi kapatma konusunda endişelenmenize gerek kalmaz.

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.