使用Javascript / jQuery下载文件

时间:2010-09-20 06:58:25

标签: javascript jquery download

我有一个非常相似的要求here

我需要让用户的浏览器在$('a#someID').click();

时手动开始下载

但我无法使用window.href方法,因为它会将当前页面内容替换为您尝试下载的文件。

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

28 个答案:

答案 0 :(得分:351)

使用不可见的<iframe>

<iframe id="my_iframe" style="display:none;"></iframe>
<script>
function Download(url) {
    document.getElementById('my_iframe').src = url;
};
</script>

要强制浏览器下载文件,否则它将能够呈现(例如HTML或文本文件),您需要服务器将文件的MIME Type设置为无意义的值,例如{{1或者application/x-please-download-me,用于任意二进制数据。

如果您只想在新标签页中打开它,唯一的方法是让用户点击其application/octet-stream属性设置为target的链接。

在jQuery中:

_blank

只要点击该链接,它就会在新的标签/窗口中下载文件。

答案 1 :(得分:142)

我创建了jQuery File Download pluginDemo)(GitHub),这也有助于您的情况。它与iframe非常相似,但有一些很酷的功能,我发现它非常方便:

  • 很容易设置好的视觉效果(jQuery UI对话,但不是必需的),一切都经过测试

  • 用户永远不会离开他们发起文件下载的同一页面。此功能对于现代Web应用程序变得至关重要

  • successCallback和failCallback函数允许您明确用户在任一情况下看到的内容

  • 与jQuery UI一起,开发人员可以轻松地显示一个模式告诉用户文件下载正在发生,在下载开始后解除模式,甚至以友好的方式通知用户发生了错误。有关此示例,请参阅Demo。希望这有助于某人!

这是一个使用带有promises的插件source的简单用例演示。 demo page还包括许多其他“更好的用户体验”示例。

$.fileDownload('some/file.pdf')
    .done(function () { alert('File download a success!'); })
    .fail(function () { alert('File download failed!'); });

答案 2 :(得分:118)

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

检查目标浏览器是否能顺利运行上述代码段:
http://caniuse.com/#feat=download

答案 3 :(得分:63)

我很惊讶没有很多人知道元素的下载属性。请帮忙宣传它!你可以有一个隐藏的HTML链接,并伪造它点击它。如果html链接具有下载属性,则无论如何都会下载该文件,而不是查看它。这是代码。如果它可以找到它,它将下载猫图片。

&#13;
&#13;
document.getElementById('download').click();
&#13;
<a href="https://docs.google.com/uc?id=0B0jH18Lft7ypSmRjdWg1c082Y2M" download id="download" hidden></a>
&#13;
&#13;
&#13;

注意: 并非所有浏览器都支持此功能:http://www.w3schools.com/tags/att_a_download.asp

答案 4 :(得分:46)

我建议使用html5代替jQuery:

<a href="your_link" download> file_name </a>

这将下载您的文件,而无需打开它。

答案 5 :(得分:20)

如果您已经在使用jQuery,则可以利用它来生成更小的片段 安德鲁答案的jQuery版本:

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

答案 6 :(得分:12)

适用于Chrome,Firefox和IE8及更高版本。

var link=document.createElement('a');
document.body.appendChild(link);
link.href=url ;
link.click();

答案 7 :(得分:10)

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

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

我在

中对此进行了测试
  • Chrome 55
  • Firefox 50
  • Edge IE8-10
  • iOS 10(Safari / Chrome)
  • Android Chrome

如果有人知道这个解决方案的任何缺点,我会很高兴听到他们。

完整演示:

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

答案 8 :(得分:10)

使用iframe

的简单示例
function downloadURL(url) {
    var hiddenIFrameID = 'hiddenDownloader',
        iframe = document.getElementById(hiddenIFrameID);
    if (iframe === null) {
        iframe = document.createElement('iframe');
        iframe.id = hiddenIFrameID;
        iframe.style.display = 'none';
        document.body.appendChild(iframe);
    }
    iframe.src = url;
};

然后只需在任何地方调用该函数:

downloadURL('path/to/my/file');

答案 9 :(得分:4)

如果不需要浏览其他页面,这可能会有所帮助。 这是基本的javascript函数,因此可以在Javascript后端的任何平台中使用

window.location.assign('any url or file path')

答案 10 :(得分:4)

下载数据的最完整和工作(测试)代码FireFox,Chrome和IE代码如下。假设数据位于 texarea 字段中, id ='textarea_area' filename 是将下载数据的文件名。

constructor(props) {
    super(props);
    this.state = {
        disabled: false
    };
}

render() {
    return(
        <TouchableOpacity disabled={this.state.disabled}>
            <Text>Click</Text>
        </TouchableOpacity>
    )
}

然后只需致电

function download(filename) {
    if (typeof filename==='undefined') filename = ""; // default
    value = document.getElementById('textarea_area').value;

    filetype="text/*";
    extension=filename.substring(filename.lastIndexOf("."));
    for (var i = 0; i < extToMIME.length; i++) {
        if (extToMIME[i][0].localeCompare(extension)==0) {
            filetype=extToMIME[i][1];
            break;
        }
    }


    var pom = document.createElement('a');
    pom.setAttribute('href', 'data: '+filetype+';charset=utf-8,' + '\ufeff' + encodeURIComponent(value)); // Added BOM too
    pom.setAttribute('download', filename);


    if (document.createEvent) {
        if (navigator.userAgent.indexOf('MSIE') !== -1 || navigator.appVersion.indexOf('Trident/') > 0) { // IE
            blobObject = new Blob(['\ufeff'+value]);
            window.navigator.msSaveBlob(blobObject, filename);
        } else { // FF, Chrome
            var event = document.createEvent('MouseEvents');
            event.initEvent('click', true, true);
            pom.dispatchEvent(event);
        }
    } else if( document.createEventObject ) { // Have No Idea
        var evObj = document.createEventObject();
        pom.fireEvent( 'onclick' , evObj );
    } else { // For Any Case
        pom.click();
    }

}

下载发起。

用于为下载对话框设置正确MIME类型的数组可以如下:

<a href="javascript:download();">Download</a>

答案 11 :(得分:4)

也许只是让您的javascript打开一个只下载文件的页面,就像将下载链接拖到新标签页一样:

Window.open("https://www.MyServer.
Org/downloads/ardiuno/WgiWho=?:8080")

打开的窗口打开一个自动关闭的下载页面。

答案 12 :(得分:4)

我不知道问题是否太旧,但只要下载mime类型正确(例如zip存档),将window.location设置为下载URL就可以了。

var download = function(downloadURL) {

   location = downloadURL;

});

download('http://example.com/archive.zip'); //correct usage
download('http://example.com/page.html'); //DON'T

答案 13 :(得分:2)

我最终使用了以下代码段,该代码段可在大多数浏览器中使用,尽管未在IE中进行测试。

function downloadURI(uri, name) {
    let link = document.createElement("a");
    link.download = name;
    link.href = uri;
    link.style.display = "none";

    document.body.appendChild(link);
    if (typeof MouseEvent !== "undefined") {
        link.dispatchEvent(new MouseEvent("click"));
    } else {
        link.click();
    }
    document.body.removeChild(link);
}

let data = [{email: "test@domain.com", name: "test"}, {email: "anothertest@example.com", name: "anothertest"}];

let json = JSON.stringify(data);
let blob = new Blob([json], {type: "application/json"});
let url = window.URL.createObjectURL(blob);
downloadURI(url, "file.json");
window.URL.revokeObjectURL(url);

答案 14 :(得分:2)

为了改善Imagine Breaker的答案,FF&amp; IE:

var evt = document.createEvent("MouseEvents");
evt.initMouseEvent("click", true, true, window, 0, 0, 0, 0, 0, false, false, false, false, 0, null);

function downloadURI(uri, name) {
    var link = document.createElement("a");
    link.download = name;
    link.href = uri;
    link.dispatchEvent(evt);
}

换句话说,只需使用dispatchEvent函数代替click();

答案 15 :(得分:1)

来自Corbacho的优秀解决方案,我只是适应了摆脱var

function downloadURL(url) {
    if( $('#idown').length ){
        $('#idown').attr('src',url);
    }else{
        $('<iframe>', { id:'idown', src:url }).hide().appendTo('body');
    }
}

答案 16 :(得分:1)

对我来说,可以在chrome v72中正常测试

function down_file(url,name){
var a = $("<a>")
    .attr("href", url)
    .attr("download", name)
    .appendTo("body");
a[0].click();
a.remove();
}

down_file('https://www.useotools.com/uploads/nulogo[1].png','logo.png')

答案 17 :(得分:1)

hitesh在12月30日和13日提交的答案确实有效。它只需要一点调整:

PHP文件可以自行调用。换句话说,只需创建一个名为saveAs.php的文件,并将此代码放入其中......

        <a href="saveAs.php?file_source=YourDataFile.pdf">Download pdf here</a>

    <?php
        if (isset($_GET['file_source'])) {
            $fullPath = $_GET['file_source'];
            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;
            }
        }
    ?>

答案 18 :(得分:1)

这些功能在stacktrace.js中使用:

/**
 * Try XHR methods in order and store XHR factory.
 *
 * @return <Function> XHR function or equivalent
 */
var createXMLHTTPObject = function() {
    var xmlhttp, XMLHttpFactories = [
        function() {
            return new XMLHttpRequest();
        }, function() {
            return new ActiveXObject('Msxml2.XMLHTTP');
        }, function() {
            return new ActiveXObject('Msxml3.XMLHTTP');
        }, function() {
            return new ActiveXObject('Microsoft.XMLHTTP');
        }
    ];
    for (var i = 0; i < XMLHttpFactories.length; i++) {
        try {
            xmlhttp = XMLHttpFactories[i]();
            // Use memoization to cache the factory
            createXMLHTTPObject = XMLHttpFactories[i];
            return xmlhttp;
        } catch (e) {
        }
    }
}

/**
 * @return the text from a given URL
 */
function ajax(url) {
    var req = createXMLHTTPObject();
    if (req) {
        try {
            req.open('GET', url, false);
            req.send(null);
            return req.responseText;
        } catch (e) {
        }
    }
    return '';
}

答案 19 :(得分:1)

我建议您使用mousedown事件,该事件在click事件之前调用。这样,浏览器自然地处理click事件,这避免了任何代码怪异:

(function ($) {


    // with this solution, the browser handles the download link naturally (tested in chrome and firefox)
    $(document).ready(function () {

        var url = '/private/downloads/myfile123.pdf';
        $("a#someID").on('mousedown', function () {
            $(this).attr("href", url);
        });

    });
})(jQuery);

答案 20 :(得分:0)

使用锚标记和PHP可以完成,请查看此答案

JQuery Ajax call for PDF file download

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

答案 21 :(得分:0)

我在没有JQuery的情况下使用@rakaloof's solution(因为you don't need it here)。谢谢你的想法!这是一个基于vanillaJS表单的解决方案:

&#13;
&#13;
const uri = 'https://upload.wikimedia.org/wikipedia/commons/b/bb/Test_ogg_mp3_48kbps.wav';
let form = document.createElement("form");
form.setAttribute('action', uri);
document.body.appendChild(form);
form.submit();
document.body.removeChild(document.body.lastElementChild);
&#13;
&#13;
&#13;

答案 22 :(得分:0)

注意:并非所有浏览器都支持。

我一直在寻找一种使用jquery下载文件的方法,而无需从头开始在href属性中设置文件url。

&#13;
&#13;
jQuery('<a/>', {
    id: 'downloadFile',
    href: 'http://cdn.sstatic.net/Sites/stackoverflow/img/apple-touch-icon@2.png',
    style: 'display:hidden;',
    download: ''
}).appendTo('body');

$("#downloadFile")[0].click();
&#13;
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
&#13;
&#13;
&#13;

答案 23 :(得分:0)

我知道我参加晚会已经迟到了,但我想分享我的解决方案,这是上面Imagine Breaker解决方案的变体。我尝试使用他的解决方案,因为他的解决方案对我来说似乎最简单易行。但是像其他人说的那样,它对某些浏览器不起作用,所以我使用jquery对它进行了一些修改。

希望这可以帮助那些人。

okHttpClient

答案 24 :(得分:0)

Firefox和Chrome测试:

var link = document.createElement('a');
link.download = 'fileName.ext'
link.href = 'http://down.serv/file.ext';

// Because firefox not executing the .click() well
// We need to create mouse event initialization.
var clickEvent = document.createEvent("MouseEvent");
clickEvent.initEvent("click", true, true);

link.dispatchEvent(clickEvent);

这实际上是firefox的“chrome”方式解决方案(我没有在其他浏览器上测试过,所以请留下关于可编译性的评论)

答案 25 :(得分:0)

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

关于它的妙处在于它不仅可以灵活地用于URL,还可以灵活地用于您要下载的客户端数据。

  1. 文本字符串
  2. 文本dataURL
  3. 文本Blob
  4. 文本数组
  5. html字符串
  6. html blob
  7. ajax回调
  8. 二进制文件

答案 26 :(得分:0)

let args = {"data":htmlData,"filename":exampleName}

要创建HTMl文件并下载

window.downloadHTML = function(args) {
var data, filename, link;
var csv = args.data;
if (csv == null) return;
filename = args.filename || 'report.html';
data = 'data:text/html;charset=utf-8,' + encodeURIComponent(csv);
console.log(data);
link = document.createElement('a');
link.setAttribute('href', data);
link.setAttribute('download', filename);
document.body.appendChild(link);
link.click();
document.body.removeChild(link);}

创建和下载CSV

window.downloadCSV = function(args) {
var data, filename, link;
var csv = args.data;
if (csv == null) return;
filename = args.filename || 'report.csv';
if (!csv.match(/^data:text\/csv/i)) {
    csv = 'data:text/csv;charset=utf-8,' + csv;
}
data = encodeURI(csv);
link = document.createElement('a');
link.setAttribute('href', data);
link.setAttribute('download', filename);
document.body.appendChild(link);
link.click();
document.body.removeChild(link);

}

答案 27 :(得分:0)

您可以简单地使用 HTML 中的下载属性。使用好 ol' Javascript,您可以使用此功能直接下载文件。锚标签的下载属性应该指向要下载的文件所在的链接。

首先,将 URL 指向您的资源路径:

var url = 'your url goes here';

创建一个锚标签,需要的属性如下:

var elem = document.createElement('a');
elem.href = url;
elem.download = url;
elem.id="downloadAnchor";

将锚标记附加到网页的正文元素。

document.body.appendChild(elem);

现在以编程方式触发点击事件。点击锚标签将触发下载。

$('#downloadAnchor').click();

综合起来:

var url = 'your url goes here';
var elem = document.createElement('a');
elem.href = url;
elem.download = url;
elem.id="downloadAnchor";
document.body.appendChild(elem);
$('#downloadAnchor').click();

附加信息:上面的代码没有什么特别的,只是在 Chrome Devtools 的控制台中运行的客户端 JavaScript,但功能强大,还开辟了很多可能性,比如网页抓取。

例如在 Devtools 控制台中执行的以下代码块将在新选项卡中打开页面中的所有链接: 只需转到 this webpage ,打开 devtools 并在浏览器控制台中运行此脚本,然后观察 JavaScript 的威力。 (注意:以下代码仅用于教育目的。)

确保为该网站启用弹出窗口,否则默认弹出窗口阻止程序将禁用您的锚点点击。

var links = document.getElementsByClassName("_3ATBKe");
for(var i=0;i<links.length;i++){
    var title = document.getElementsByClassName("_3ATBKe")[i].firstElementChild.firstElementChild.innerText.replaceAll('|','-').replaceAll(':','x');
    console.log('Opening..'+title);
    links[i].firstElementChild.click();
}

注意:这不仅限于锚点点击,您几乎可以下载在网页上找到的任何内容。如果您的网页上加载了某些内容(图像、音频、视频),您可能可以编写一个脚本来下载它,即使 UI 未向您提供该设置。