วิธีที่ง่ายที่สุดในการเปิดหน้าต่างดาวน์โหลดโดยไม่ต้องออกจากหน้า


119

วิธีใดเป็นวิธีที่ดีที่สุดในการเปิดกล่องโต้ตอบการดาวน์โหลด (สมมติว่าเราสามารถตั้งค่าการจัดการเนื้อหา: ไฟล์แนบในส่วนหัว) โดยไม่ต้องออกจากหน้าปัจจุบันหรือเปิดป๊อปอัปซึ่งทำงานได้ไม่ดีใน Internet Explorer (IE ) 6.

คำตอบ:


107

7 ปีผ่านไปและฉันไม่รู้ว่ามันใช้ได้กับ IE6 หรือไม่ แต่สิ่งนี้จะแจ้งให้ OpenFileDialog ใน FF และ 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);

ก่อนอื่นขอขอบคุณสำหรับวิธีแก้ปัญหานี้ แต่ฉันพบข้อผิดพลาดหาก removeChild (a) zip จะแตกข้อผิดพลาดด้วย zip เสียดังนั้นให้ลบรหัสนี้ออกเพื่อแก้ปัญหา
รอย

2
@Manoj Rana - ฉันได้ตรวจสอบ FF 58.0.2 (64 บิต) มันใช้งานได้ จะใช้ไม่ได้กับ FF ใด ๆ ถ้าคุณลบ 2 บรรทัดdocument.body.appendChild (a); document.body.removeChild (ก);
0x000f

1
เพื่อให้ทำงานบน Edge 16 ส่วนหัวจากที่มาของไฟล์ควรมีContent-Type: application/octet-streamและContent-Disposition: attachment.
Simon

12
สิ่งนี้ใช้ไม่ได้อีกต่อไปdevelopers.google.com/web/updates/2018/02/…
Paulius Dragunas

2
โครเมี่ยม @ user1933131 จะนำออกเฉพาะสำหรับ cross-origin เท่านั้น
Brandy23

202

จาวาสคริปต์นี้ดีที่ไม่เปิดหน้าต่างหรือแท็บใหม่

window.location.assign(url);

18
เช่นเดียวกับ window.location = url; “ เมื่อใดก็ตามที่กำหนดค่าใหม่ให้กับวัตถุตำแหน่งเอกสารจะถูกโหลดโดยใช้ URL ราวกับว่า window.location.assign () ถูกเรียกด้วย URL ที่แก้ไข” - developer.mozilla.org/en-US/docs/ Web / API / window.location
Rob Juurlink

13
ซึ่งทำให้การเชื่อมต่อ WebSocket ตัดการเชื่อมต่อ
igorpavlov

4
ฉันใช้โซลูชันเดียวกัน แต่เปิดไฟล์ในแท็บเดียวกันแทนที่จะเปิดกล่องโต้ตอบดาวน์โหลด
เทคโนแครกเกอร์

2
เหมือนกับ window.open (url, '_self') ถ้า url เป็นหน้าดาวน์โหลด
ผู้เชี่ยวชาญอยากเป็น

5
เมื่อใช้ IE11 ฉันพบว่าสิ่งนี้ทำให้ JS หยุดทำงาน ดังนั้นสำหรับ IE 11 ฉันจึงใช้ window.open (url, '_blank') ซึ่งเปิดแท็บอื่น แต่แท็บนั้นปิดเมื่อใช้งานได้ไฟล์เป็นการดาวน์โหลด สิ่งนี้ทำให้ JS ทำงานต่อไป
ลุค

23

ฉันมักจะเพิ่ม target = "_ blank" ในลิงค์ดาวน์โหลด หน้าต่างใหม่จะเปิดขึ้น แต่ทันทีที่ผู้ใช้คลิกบันทึกหน้าต่างใหม่จะปิดลง


2
นี่คือคำตอบที่ดีที่สุด ใน Internet Explorer การเพิ่ม "target =" _ blank "'ลงในลิงก์ที่จะดาวน์โหลดจะหยุดไม่ให้เบราว์เซอร์นำทางออกไป (โดยที่" HTML1300: การนำทางเกิดขึ้นจะถูกพิมพ์ออกมา ") และทำให้หน้าเว็บอยู่ในสถานะที่ไม่สอดคล้องกันได้
user64141

23

ใส่สิ่งนี้ในส่วนหัวของ HTML โดยตั้งค่าurlvar เป็น URL ของไฟล์ที่จะดาวน์โหลด:

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

จากนั้นใส่สิ่งนี้ไว้ในเนื้อหาซึ่งจะเริ่มการดาวน์โหลดโดยอัตโนมัติหลังจาก 5 วินาที:

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

(จากที่นี่ )


2
ไม่ได้ผลเพราะใน IE6 หากผู้ใช้คลิก "บันทึก" ไฟล์จะถูกบันทึก แต่ป๊อปอัปยังคงเปิดอยู่ สิ่งนี้ไม่สามารถยอมรับได้
mkoryak

รหัสนี้ใช้ไม่ได้ในซาฟารีโปรดช่วยฉันแก้ไขในซาฟารีได้ไหม
Renish Khunt

17

ฉันรู้ว่าคำถามที่ถูกถาม7 years and 9 months agoแต่โซลูชั่นโพสต์หลายคนดูเหมือนจะไม่ทำงานเช่นใช้<iframe>เท่านั้นทำงานร่วมกับและไม่ได้ทำงานกับFireFoxChrome

ทางออกที่ดีที่สุด:

วิธีแก้ปัญหาการทำงานที่ดีที่สุดในการเปิดป๊อปอัปดาวน์โหลดไฟล์JavaScriptคือการใช้HTMLองค์ประกอบลิงก์โดยไม่จำเป็นต้องต่อท้ายองค์ประกอบลิงก์document.bodyตามที่ระบุไว้ในคำตอบอื่น ๆ

คุณสามารถใช้ฟังก์ชันต่อไปนี้:

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

ในแอปพลิเคชันของฉันฉันใช้วิธีนี้:

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

การสาธิตการทำงาน:

บันทึก:

  • คุณต้องใช้link.downloadแอตทริบิวต์เพื่อไม่ให้เบราว์เซอร์เปิดไฟล์ในแท็บใหม่และเริ่มการดาวน์โหลดป๊อปอัป
  • สิ่งนี้ได้รับการทดสอบกับไฟล์หลายประเภท (docx, xlsx, png, pdf, ... )

วิธีใดเป็นวิธีที่ดีที่สุดในการแสดง gif ที่กำลังโหลดจนกว่าไฟล์จะดาวน์โหลด
Ctrl_Alt_Defeat

1
@Ctrl_Alt_Defeat ในกรณีนี้การติดตามขั้นตอนการดาวน์โหลดไม่ใช่เรื่องง่าย แต่เคล็ดลับอย่างหนึ่งคือสามารถแสดงภาพเคลื่อนไหว gif นี้เมื่อlinkคลิกและซ่อนหลังจากหมดเวลาโดยใช้รหัสนี้: link.onclick = function() { document.body.innerText = "The file is being downloaded ..."; setTimeout(function() { document.body.innerText = ""; }, 2000); }คุณจะเห็นว่ามันทำงานในสิ่งนี้ ไวโอลินAjaxแต่เก็บไว้ในใจว่ามันไม่ได้เป็นวิธีที่แนะนำให้ทำมันก็จะได้รับการจัดการที่ดีกว่าถ้าเราได้ใช้
cнŝdk

1
มันใช้ไม่ได้กับ firefox จะดาวน์โหลดใน firefox ได้อย่างไร?
Manoj Rana

@ManojRana สำหรับ firefox คุณสามารถใช้iframeดูคำตอบนี้
cнŝdk

2
วิธีนี้ใช้ได้กับ Chrome, Safari และ Firefox สำหรับฉัน :)
ariebear

15

ฉันกำลังมองหาวิธีที่ดีในการใช้จาวาสคริปต์เพื่อเริ่มการดาวน์โหลดไฟล์ตามที่คำถามนี้แนะนำ อย่างไรก็ตามคำตอบเหล่านี้ไม่เป็นประโยชน์ จากนั้นฉันได้ทำการทดสอบ xbrowser และพบว่า iframe ทำงานได้ดีที่สุดในเบราว์เซอร์สมัยใหม่ทั้งหมด 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" คลาสของฉันเป็นสไตล์เนื้อหาที่มีอยู่ แต่ไม่สามารถดูได้

css:

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

เหมือนกับ. visuallyHidden ใน html5boilerplate

ฉันชอบสิ่งนี้กับเมธอด javascript window.open เพราะหากลิงก์เสียวิธี iframe ก็จะไม่ทำอะไรเลยตรงข้ามกับการเปลี่ยนเส้นทางไปยังหน้าว่างโดยบอกว่าไฟล์ไม่สามารถเปิดได้

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 Object-URL File 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)


2
รู้สึกว่านี่คือวิธีที่ดีที่สุด !!
Kushal MK

1
นอกจากนี้ยังเป็นแนวทางปฏิบัติที่ดีในการโทรURL.revokeObjectURL(url)เมื่อไม่จำเป็นต้องใช้ไฟล์เพื่อเพิ่มหน่วยความจำอีกต่อไป
SleepWalker

5

การแก้ไขตำแหน่งของหน้าต่างอาจทำให้เกิดปัญหาบางอย่างโดยเฉพาะอย่างยิ่งเมื่อคุณมีการเชื่อมต่อแบบต่อเนื่องเช่น websocket ดังนั้นฉันมักจะใช้โซลูชัน iframe แบบเก่าที่ดี

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

หากลิงก์ไปยัง url ของไฟล์ที่ถูกต้องเพียงแค่กำหนด window.location.href ก็จะได้ผล

อย่างไรก็ตามบางครั้งลิงก์ไม่ถูกต้องและจำเป็นต้องใช้ iFrame

ทำ event.preventDefault ปกติของคุณเพื่อป้องกันไม่ให้หน้าต่างเปิดขึ้นและหากคุณใช้ jQuery สิ่งนี้จะได้ผล:

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

2

หลังจากพยายามหลายชั่วโมงฟังก์ชั่นก็เกิดขึ้น :) ฉันมีสถานการณ์ที่ฉันต้องแสดงตัวโหลดให้ทันเวลาในขณะที่ไฟล์กำลังเตรียมดาวน์โหลด:

ทำงานใน Chrome, Safari และ 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

เกี่ยวกับ:

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

วิธีนี้ใช้ได้กับทุกเบราว์เซอร์ (ฉันคิดว่า) และให้คุณใส่ข้อความเช่น: "หากการดาวน์โหลดไม่เริ่มในห้าวินาทีให้คลิกที่นี่"

ถ้าคุณจำเป็นต้องใช้จาวาสคริปต์.. ดี ...

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

ความนับถือ


0

iframe ขนาดเล็ก / ซ่อนอยู่สามารถทำงานเพื่อจุดประสงค์นี้ได้

ด้วยวิธีนี้คุณไม่ต้องกังวลเกี่ยวกับการปิดป๊อปอัป

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.