在不离开页面的情况下打开下载窗口的最简单方法

时间:2009-06-30 22:40:09

标签: javascript

打开下载对话框的最佳跨浏览器方式是什么(假设我们可以设置内容处理:标题中的附件)而无需导航离开当前页面,或打开弹出窗口,这在IE6中无法正常工作。 / p>

13 个答案:

答案 0 :(得分:183)

这个javascript很不错,它不会打开新的窗口或标签。

window.location.assign(url);

答案 1 :(得分:82)

7年过去了,好的。 我不知道它是否适用于IE6,但这会在FF和Chrome中提示OpenFileDialog。

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

答案 2 :(得分:22)

我总是在下载链接中添加一个target =“_ blank”。这将打开一个新窗口,但只要用户单击“保存”,新窗口就会关闭。

答案 3 :(得分:17)

将其放在HTML head部分,将url var设置为要下载的文件的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> 

(来自here。)

答案 4 :(得分:14)

我一直在寻找一种使用javascript来启动文件下载的好方法,正如这个问题所暗示的那样。然而,这些答案没有帮助。然后,我做了一些xbrowser测试,发现iframe在所有现代浏览器上运行得最好IE&gt; 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; 
}

与html5boilerplate中的.visuallyHidden相同

我更喜欢这个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();

答案 5 :(得分:7)

我知道问题是7 years and 9 months ago,但许多发布的解决方案似乎不起作用,例如使用<iframe>仅适用于FireFox,但不适用于{{ 1}}。

最佳解决方案:

Chrome中打开文件下载弹出窗口的最佳working solution是使用JavaScript链接元素,而无需将链接元素附加到{ {1}} ,如其他答案中所述。

您可以使用以下功能:

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'); 属性,因此浏览器不会 在新选项卡中打开文件并触发下载弹出窗口。
  • 这是使用多种文件类型(docx,xl​​sx,png,pdf,...)进行测试的。

答案 6 :(得分:5)

如果链接指向有效的文件网址,只需指定window.location.href即可。

但是,有时链接无效,并且需要iFrame。

执行正常的event.preventDefault以防止窗口打开,如果您使用的是jQuery,这将有效:

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

答案 7 :(得分:4)

修改窗口的位置可能会导致一些问题,尤其是当您拥有像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();
}

答案 8 :(得分:2)

使用HTML5 Blob 对象-URL文件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)

答案 9 :(得分:1)

根据新的 chrome 规范 https://developers.google.com/web/updates/2018/02/chrome-65-deprecations

的最佳解决方案

原生 JavaScript

public static downloadFile(url: string): void {
     const xmlHttp = new XMLHttpRequest();
     xmlHttp.onreadystatechange = () => {
       if (xmlHttp.readyState === 4 && xmlHttp.status === 200) {
         const blobUrl = window.URL.createObjectURL(xmlHttp.response);
         const e = document.createElement('a');
         e.href = blobUrl;
         e.download = blobUrl.substr(blobUrl.lastIndexOf('/') + 1);
         document.body.appendChild(e);
         e.click();
         document.body.removeChild(e);
       }
     };
     xmlHttp.responseType = 'blob';
     xmlHttp.open('GET', url, true);
     xmlHttp.send(null);
   }

如果您使用的是 angular,请试试这个。

async downloadBrochure(url: string) {
    try {
      const res = await this.httpClient.get(url, { responseType: 'blob' }).toPromise();
      this.downloadFile(res);
    } catch (e) {
      console.log(e.body.message);
    }
  }

  downloadFile(data) {
    const url = window.URL.createObjectURL(data);
    const e = document.createElement('a');
    e.href = url;
    e.download = url.substr(url.lastIndexOf('/') + 1);
    document.body.appendChild(e);
    e.click();
    document.body.removeChild(e);
  }

答案 10 :(得分:0)

怎么样:

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

这种方式适用于所有浏览器(我认为)并让您发出如下消息:“如果下载没有在五秒内开始,请单击此处。”

如果你需要它与javascript ..好吧......

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

此致

答案 11 :(得分:0)

小/隐藏的iframe可以用于此目的。

这样你就不用担心关闭弹出窗口了。

答案 12 :(得分:0)

经过数小时的尝试,该函数诞生了:)我有一种情况,我必须在文件准备下载时及时显示加载程序:

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