Cách dễ nhất để mở cửa sổ tải xuống mà không cần điều hướng khỏi trang


118

Cách tốt nhất trên nhiều trình duyệt để mở hộp thoại tải xuống (giả sử chúng ta có thể đặt content-disposion: file đính kèm trong tiêu đề) mà không cần điều hướng khỏi trang hiện tại hoặc mở cửa sổ bật lên, cách này không hoạt động tốt trong Internet Explorer (IE ) 6.

Câu trả lời:


106

Đã 7 năm trôi qua và tôi không biết liệu nó có hoạt động với IE6 hay không, nhưng điều này nhắc nhở OpenFileDialog trong FF và Chrome.

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

Đầu tiên cảm ơn bạn cho giải pháp này, nhưng tôi tìm thấy một lỗi nếu removeChild (a) zip sẽ giải nén lỗi với zip bị hỏng, nên loại bỏ mã này giải quyết nó
Roy

2
@Manoj Rana - Tôi đã kiểm tra trên FF 58.0.2 (64-bit) nó đang hoạt động. Nó sẽ không hoạt động trên bất kỳ FF nào nếu bạn xóa 2 dòng document.body.appendChild (a); document.body.removeChild (a);
0x000f

1
Để làm cho nó hoạt động trên Edge 16, tiêu đề, từ nơi tệp đến, phải chứa Content-Type: application/octet-streamContent-Disposition: attachment.
Simon


2
@ user1933131 chrome chỉ loại bỏ cho cross-nguồn gốc
Brandy23

200

Javascript này rất hay là nó không mở ra một cửa sổ hoặc tab mới.

window.location.assign(url);

17
Điều này cũng giống như window.location = url; “Bất cứ khi nào một giá trị mới được gán cho đối tượng vị trí, một tài liệu sẽ được tải bằng URL như thể window.location.assign () đã được gọi bằng URL đã sửa đổi” - developer.mozilla.org/en-US/docs/ Web / API / window.location
Rob Juurlink

13
Điều này khiến kết nối WebSocket bị ngắt kết nối.
igorpavlov

4
Tôi đã sử dụng cùng một giải pháp nhưng nó mở tệp trong cùng một tab thay vì mở hộp thoại tải xuống.
Techno Cracker

2
nó giống với window.open (url, '_self') nếu lúc đó url dành cho trang tải xuống.
Chuyên gia muốn trở thành

5
Khi sử dụng IE11, tôi thấy rằng điều này khiến JS dừng lại. Vì vậy, đối với IE 11, tôi đã sử dụng window.open (url, '_blank'), tab này đã mở một tab khác, tuy nhiên tab đó đã đóng lại khi xem tệp là bản tải xuống. Điều này giữ cho JS tiếp tục chạy.
Luke

23

Tôi luôn thêm target = "_ blank" vào liên kết tải xuống. Thao tác này sẽ mở ra một cửa sổ mới, nhưng ngay sau khi người dùng nhấp vào lưu, cửa sổ mới sẽ bị đóng lại.


2
Đây là câu trả lời tốt nhất. Trong Internet Explorer, việc thêm 'target = "_ blank"' vào một liên kết sẽ được tải xuống sẽ ngăn trình duyệt điều hướng đi (nơi "HTML1300: Điều hướng xảy ra" được in) và do đó có thể khiến trang ở trạng thái không nhất quán.
user64141 28/02/17

23

Đặt cái này vào phần đầu HTML, đặt urlvar thành URL của tệp sẽ được tải xuống:

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

Sau đó đặt cái này vào phần thân, quá trình này sẽ tự động bắt đầu tải xuống sau 5 giây:

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

(Từ đây .)


2
điều đó không hoạt động, bởi vì trong IE6, nếu người dùng nhấp vào "lưu", tệp sẽ được lưu, nhưng cửa sổ bật lên vẫn mở. Không thể chấp nhận được.
mkoryak

mã này không hoạt động trong safari, bạn có thể giúp tôi giải quyết trong safari được không.
Renish Khunt

17

Tôi biết câu hỏi đã được đặt ra 7 years and 9 months agonhưng nhiều giải pháp đã đăng dường như không hoạt động, chẳng hạn như sử dụng một giải pháp <iframe>chỉ hoạt động với FireFoxvà không hoạt động với Chrome.

Giải pháp tốt nhất:

Giải pháp hoạt động tốt nhất để mở cửa sổ bật lên tải xuống tệp JavaScriptlà sử dụng HTMLphần tử liên kết, không cần nối phần tử liên kết vàodocument.body như đã nêu trong các câu trả lời khác.

Bạn có thể sử dụng chức năng sau:

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

Trong ứng dụng của tôi, tôi đang sử dụng nó theo cách này:

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

Demo làm việc:

Ghi chú:

  • Bạn phải sử dụng link.downloadthuộc tính để trình duyệt không mở tệp trong tab mới và kích hoạt cửa sổ bật lên tải xuống.
  • Điều này đã được thử nghiệm với một số loại tệp (docx, xlsx, png, pdf, ...).

Cách tốt nhất để hiển thị gif đang tải cho đến khi tệp được tải xuống là gì?
Ctrl_Alt_Defeat

1
@Ctrl_Alt_Defeat Trong trường hợp này, sẽ không dễ dàng theo dõi quá trình tải xuống, nhưng một mẹo có thể là hiển thị hoạt ảnh gif này khi linknhấp chuột và ẩn nó sau một khoảng thời gian chờ, bằng cách sử dụng mã này:, link.onclick = function() { document.body.innerText = "The file is being downloaded ..."; setTimeout(function() { document.body.innerText = ""; }, 2000); }bạn có thể thấy nó hoạt động trong điều này khó khăn , nhưng hãy nhớ rằng đó không phải là cách được khuyến nghị để làm điều đó, nó sẽ được xử lý tốt hơn nếu chúng ta đang sử dụng Ajax.
cнŝdk

1
nó không hoạt động trong firefox. làm thế nào để tải xuống trong firefox?
Manoj Rana

@ManojRana Đối với firefox, bạn có thể sử dụng câu trả lờiiframe xem câu trả lời này .
cнŝdk Ngày

2
Giải pháp này hoạt động trên Chrome, Safari và Firefox đối với tôi :)
chào mừng

15

Tôi đang tìm một cách hay để sử dụng javascript để bắt đầu tải xuống tệp, giống như câu hỏi này gợi ý. Tuy nhiên những câu trả lời này không hữu ích. Sau đó, tôi đã thực hiện một số thử nghiệm xbrowser và nhận thấy rằng iframe hoạt động tốt nhất trên tất cả các trình duyệt hiện đại 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" là lớp của tôi để tạo kiểu cho nội dung hiện có nhưng không thể xem được.

css:

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

giống như .vis VisualHidden trong html5boilerplate

Tôi thích điều này hơn phương thức window.open của javascript vì nếu liên kết bị hỏng, phương thức iframe chỉ đơn giản là không làm bất cứ điều gì trái ngược với việc chuyển hướng đến một trang trống nói rằng không thể mở tệp.

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

Sử dụng API tệp URL đối tượng HTML5 Blob :

/**
 * 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
Tôi cảm thấy đây là cách tốt nhất để làm điều đó !!
Kushal MK

1
Nó cũng là một thực hành tốt để gọi URL.revokeObjectURL(url), khi tệp không còn cần thiết để giải phóng bộ nhớ
SleepWalker

5

Việc sửa đổi vị trí của cửa sổ có thể gây ra một số vấn đề, đặc biệt là khi bạn có kết nối liên tục như websocket. Vì vậy, tôi luôn sử dụng giải pháp iframe cũ tốt.

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

Nếu liên kết đến một url tệp hợp lệ, chỉ cần gán window.location.href sẽ hoạt động.

Tuy nhiên, đôi khi liên kết không hợp lệ và cần phải có iFrame.

Thực hiện event.preventDefault bình thường của bạn để ngăn cửa sổ mở và nếu bạn đang sử dụng jQuery, điều này sẽ hoạt động:

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

2

Sau nhiều giờ cố gắng, hàm được sinh ra :) Tôi đã gặp một tình huống mà tôi phải hiển thị trình tải kịp thời trong khi tệp đang chuẩn bị tải xuống:

Làm việc trong Chrome, Safari và 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)
        }
    });

0

Làm thế nào về:

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

Cách này hoạt động trên tất cả các trình duyệt (tôi nghĩ) và cho phép bạn đặt một thông báo như: "Nếu quá trình tải xuống không bắt đầu sau năm giây, hãy nhấp vào đây."

Nếu bạn cần nó với javascript .. thì ...

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

Trân trọng


0

Một iframe nhỏ / ẩn có thể hoạt động cho mục đích này.

Bằng cách đó, bạn không phải lo lắng về việc đóng cửa sổ bật lên.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.