使用Javascript / jQuery下载文件

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

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

但是我不能使用window.href方法,因为它会用你正在下载的文件replace当前页面的内容。

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

使用一个不可见的<iframe>

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

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

如果您只想在新选项卡中打开它,唯一的方法是用户点击一个链接,其target属性设置为_blank

在jQuery中:

 $('a#someID').attr({target: '_blank', href : 'http://localhost/directory/file.pdf'}); 

无论何时该链接被点击,它将下载文件在一个新的选项卡/窗口。

我已经创build了jQuery的文件下载插件 ( 演示 )( GitHub ),这也可以帮助您的情况。 它与iframe的工作方式非常类似,但有一些很酷的function,我发现它非常方便:

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

  • 用户永远不会离开他们发起文件下载的同一页面。 这个function正在成为现代Web应用的关键

  • successCallback和failCallback函数允许您明确地了解用户在两种情况下看到的内容

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

这是一个简单的用例演示,使用带有promise的插件源代码 。 演示页面还包括许多其他“更好的用户体验”示例。

 $.fileDownload('some/file.pdf') .done(function () { alert('File download a success!'); }) .fail(function () { alert('File download failed!'); }); 
 function downloadURI(uri, name) { var link = document.createElement("a"); link.download = name; link.href = uri; link.click(); } 

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

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

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

我build议使用html5下载,而不是jQuery:

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

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

如果您已经在使用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'); 

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

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

我已经testing过了

  • Chrome 55
  • 火狐50
  • 边缘IE8-10
  • iOS 10(Safari / Chrome)
  • Android Chrome

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


完整演示:

 <html> <head><script src="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> 

适用于Chrome,Firefox和IE8及以上版本。

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

使用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; }; 

然后只需要调用你想要的function:

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

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

PHP文件可以调用自己。 换句话说,只需创build一个名为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; } } ?> 

我build议你使用mousedown事件,它被称为BEFORE点击事件。 那样的话,浏览器自然会处理点击事件,这样就避免了任何代码的怪异现象:

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

从Corbacho优秀的解决scheme,我只是适应摆脱变种

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

我使用FORM标签取得了很好的效果,因为它可以在任何地方使用,而且您不必在服务器上创build临时文件。 该方法是这样工作的。

在客户端(页面HTML),你创build一个这样的不可见的forms

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

然后你添加这个Javascript代码到你的button:

 $('#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(); 

你甚至可以像这样创build你的数据的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); 

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

我不知道这个问题是不是太老了,但只要下载MIMEtypes是正确的(例如一个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 

使用锚标签和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"); } 

这些函数在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 ''; } 

testingFirefox和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的“铬”方式解决scheme(我没有在其他浏览器上testing过,所以请留下关于编译的意见)

我知道我晚了,但我想分享我的解决scheme,这是Imagine Breaker解决scheme的变体。 我试图用他的解决scheme,因为他的解决scheme对我来说似乎最简单和容易。 但是像其他人所说的,它并不适用于某些浏览器,所以我通过使用jquery来增加一些变体。

希望这可以帮助那里的人。

 function download(url) { var link = document.createElement("a"); $(link).click(function(e) { e.preventDefault(); window.location.href = url; }); $(link).click(); } 

注意:不支持所有浏览器。

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

 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(); 
 <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script> 

我使用@ rakaloof没有JQuery 的解决scheme (因为你不需要它 )。 谢谢你的想法! 这是一个基于forms的vanillaJS解决scheme:

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

为了改进Imagine Breaker的答案,FF&IE支持这个function:

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

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

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

随着打开的窗口打开一个自动closures的下载页面。