我在这里指定了一个非常类似的需求。

我需要有用户的浏览器手动启动下载时$('a#someID').click();

但是我不能用窗户。Href方法,因为它将当前页面内容替换为您试图下载的文件。

相反,我想在新窗口/标签中打开下载。这怎么可能呢?


当前回答

在尝试下载文件时,会发生很多小事情。浏览器之间的不一致性本身就是一场噩梦。我最终使用了这个很棒的小图书馆。 https://github.com/rndme/download

它的优点是它的灵活性,不仅url,而且客户端数据你想要下载。

文本字符串 文本dataURL 文本的团 文本数组 html字符串 html的团 ajax回调 二进制文件

其他回答

我使用FORM标签有很好的结果,因为它可以在任何地方工作,你不必在服务器上创建临时文件。方法是这样的。

在客户端(页面HTML),您可以创建这样一个不可见的表单

<form method="POST" action="/download.php" target="_blank" id="downloadForm">
    <input type="hidden" name="data" id="csv">
</form>

然后你添加Javascript代码到你的按钮:

$('#button').click(function() {
     $('#csv').val('---your data---');
     $('#downloadForm').submit();
}

在服务器端,你在download.php中有如下PHP代码:

<?php
header('Content-Type: text/csv');
header('Content-Description: File Transfer');
header('Content-Type: application/octet-stream');
header('Content-Disposition: attachment; filename=out.csv');
header('Content-Transfer-Encoding: binary');
header('Connection: Keep-Alive');
header('Expires: 0');
header('Cache-Control: must-revalidate, post-check=0, pre-check=0');
header('Pragma: public');
header('Content-Length: ' . strlen($data));

echo $_REQUEST['data'];
exit();

你甚至可以像这样创建数据的zip文件:

<?php

$file = tempnam("tmp", "zip");

$zip = new ZipArchive();
$zip->open($file, ZipArchive::OVERWRITE);
$zip->addFromString('test.csv', $_REQUEST['data']);
$zip->close();

header('Content-Type: application/zip');
header('Content-Length: ' . filesize($file));
header('Content-Disposition: attachment; filename="file.zip"');
readfile($file);
unlink($file); 

最好的部分是它不会在您的服务器上留下任何残留文件,因为一切都是在运行中创建和销毁的!

我最终使用了下面的代码片段,它可以在大多数浏览器中运行,但没有在IE中进行测试。

let data = JSON.stringify([{email: "test@domain.com", name: "test"}, {email: "anothertest@example.com", name: "anothertest"}]); let type = "application/json", name = "testfile.json"; downloader(data, type, name) function downloader(data, type, name) { let blob = new Blob([data], {type}); let url = window.URL.createObjectURL(blob); downloadURI(url, name); window.URL.revokeObjectURL(url); } function downloadURI(uri, name) { let link = document.createElement("a"); link.download = name; link.href = uri; link.click(); }

更新

function downloadURI(uri, name) {
    let link = document.createElement("a");
    link.download = name;
    link.href = uri;
    link.click();
}

function downloader(data, type, name) {
    let blob = new Blob([data], {type});
    let url = window.URL.createObjectURL(blob);
    downloadURI(url, name);
    window.URL.revokeObjectURL(url);
}

使用锚标签和PHP它可以做到,检查这个答案

JQuery Ajax调用PDF文件下载

HTML
    <a href="www.example.com/download_file.php?file_source=example.pdf">Download pdf here</a>

PHP
<?php
$fullPath = $_GET['fileSource'];
if($fullPath) {
    $fsize = filesize($fullPath);
    $path_parts = pathinfo($fullPath);
    $ext = strtolower($path_parts["extension"]);
    switch ($ext) {
        case "pdf":
        header("Content-Disposition: attachment; filename=\"".$path_parts["basename"]."\""); // use 'attachment' to force a download
        header("Content-type: application/pdf"); // add here more headers for diff. extensions
        break;
        default;
        header("Content-type: application/octet-stream");
        header("Content-Disposition: filename=\"".$path_parts["basename"]."\"");
    }
    if($fsize) {//checking if file size exist
      header("Content-length: $fsize");
    }
    readfile($fullPath);
    exit;
}
?>

我正在检查文件大小,因为如果你从CDN cloudfront加载pdf,你不会得到文档的大小,这迫使文档下载为0kb,为了避免这种情况,我正在检查这种情况

 if($fsize) {//checking if file size exist
      header("Content-length: $fsize");
    }

仅仅7年之后,这里出现了一行jQuery解决方案,使用表单而不是iframe或链接:

$('<form></form>')
     .attr('action', filePath)
     .appendTo('body').submit().remove();

我已经测试过了

Chrome 55 Firefox 50 边缘IE8-10 iOS 10 (Safari/Chrome) Android浏览器

如果有人知道这个解决方案的任何缺点,我很乐意听听。


完整的演示:

<html>
<head><script src="https://code.jquery.com/jquery-1.11.3.js"></script></head>
<body>
<script>
    var filePath = window.prompt("Enter a file URL","http://jqueryui.com/resources/download/jquery-ui-1.12.1.zip");
    $('<form></form>').attr('action', filePath).appendTo('body').submit().remove();
</script>
</body>
</html>

如果您已经在使用jQuery,可以利用它生成一个较小的代码片段 jQuery版本的Andrew的回答:

var $idown;  // Keep it outside of the function, so it's initialized once.
downloadURL : function(url) {
  if ($idown) {
    $idown.attr('src',url);
  } else {
    $idown = $('<iframe>', { id:'idown', src:url }).hide().appendTo('body');
  }
},
//... How to use it:
downloadURL('http://whatever.com/file.pdf');