简体   繁体   English

单击 HTML 按钮或 JavaScript 时如何触发文件下载

[英]How to trigger a file download when clicking an HTML button or JavaScript

This is crazy but I don't know how to do this, and because of how common the words are, it's hard to find what I need on search engines.这太疯狂了,但我不知道该怎么做,而且由于这些词很常见,很难在搜索引擎上找到我需要的东西。 I'm thinking this should be an easy one to answer.我认为这应该是一个容易回答的问题。

I want a simple file download, that would do the same as this:我想要一个简单的文件下载,与此相同:

<a href="file.doc">Download!</a>

But I want to use an HTML button, eg either of these:但我想使用 HTML 按钮,例如以下任一按钮:

<input type="button" value="Download!">
<button>Download!</button>

Likewise, is it possible to trigger a simple download via JavaScript?同样,是否可以通过 JavaScript 触发简单的下载?

$("#fileRequest").click(function(){ /* code to download? */ });

I'm definitely not looking for a way to create an anchor that looks like a button, use any back-end scripts, or mess with server headers or mime types.我绝对不是在寻找一种方法来创建看起来像按钮的锚点,使用任何后端脚本,或者弄乱服务器标头或 mime 类型。

You can trigger a download with the HTML5 download attribute.您可以使用 HTML5 download属性触发download

<a href="path_to_file" download="proposed_file_name">Download</a>

Where:在哪里:

  • path_to_file is a path that resolves to an URL on the same origin . path_to_file是解析为同一来源的 URL 的路径 That means the page and the file must share the same domain, subdomain, protocol (HTTP vs. HTTPS), and port (if specified).这意味着页面和文件必须共享相同的域、子域、协议(HTTP 与 HTTPS)和端口(如果指定)。 Exceptions are blob: and data: (which always work), and file: (which never works).例外是blob:data:始终有效)和file:永远无效)。
  • proposed_file_name is the filename to save to. proposed_file_name是要保存到的文件名。 If it is blank, the browser defaults to the file's name.如果为空,则浏览器默认为文件名。

Documentation: MDN , HTML Standard on downloading , HTML Standard on download , CanIUse文档: MDN下载的HTML 标准、 download HTML 标准CanIUse

For the button you can do对于按钮,你可以做

<form method="get" action="file.doc">
   <button type="submit">Download!</button>
</form>

HTML:

<button type="submit" onclick="window.open('file.doc')">Download!</button>

With jQuery:使用 jQuery:

$("#fileRequest").click(function() {
    // hope the server sets Content-Disposition: attachment!
    window.location = 'file.doc';
});

A simple JS solution:一个简单的JS解决方案:

function download(url) {
  const a = document.createElement('a')
  a.href = url
  a.download = url.split('/').pop()
  document.body.appendChild(a)
  a.click()
  document.body.removeChild(a)
}

You can do it with "trick" with invisible iframe.你可以用隐形 iframe 的“技巧”来做到这一点。 When you set "src" to it, browser reacts as if you would click a link with the same "href".当您将“src”设置为它时,浏览器的反应就像您单击具有相同“href”的链接一样。 As opposite to solution with form, it enables you to embed additional logic, for example activating download after timeout, when some conditions are met etc.与表单解决方案相反,它使您能够嵌入额外的逻辑,例如在超时后激活下载,满足某些条件等。

It is also very silient, there's no blinking new window/tab like when using window.open .它也非常安静,没有像使用window.open那样闪烁的新窗口/标签。

HTML: HTML:

<iframe id="invisible" style="display:none;"></iframe>

Javascript: Javascript:

function download() {
    var iframe = document.getElementById('invisible');
    iframe.src = "file.doc";
}

Bootstrap Version引导版本

<a class="btn btn-danger" role="button" href="path_to_file"
   download="proposed_file_name">
  Download
</a>

Documented in Bootstrap 4 docs , and works in Bootstrap 3 as well.记录在 Bootstrap 4 文档中,也适用于 Bootstrap 3。

I think this is the solution you were looking for我认为这是您正在寻找的解决方案

<button type="submit" onclick="window.location.href='file.doc'">Download!</button>

I hade a case where my Javascript generated a CSV file.我有一个案例,我的 Javascript 生成了一个 CSV 文件。 Since there is no remote URL to download it I use the following implementation.由于没有远程 URL 来下载它,我使用以下实现。

downloadCSV: function(data){
    var MIME_TYPE = "text/csv";

    var blob = new Blob([data], {type: MIME_TYPE});
    window.location.href = window.URL.createObjectURL(blob);
}

You can hide the download link and make the button click it.您可以隐藏下载链接并使按钮单击它。

<button onclick="document.getElementById('link').click()">Download!</button>
<a id="link" href="file.doc" download hidden></a>

关于什么:

<input type="button" value="Download Now!" onclick="window.location = 'file.doc';">

If your looking for a vanilla JavaScript (no jQuery) solution and without using the HTML5 attribute you could try this.如果您正在寻找一个 vanilla JavaScript(无 jQuery)解决方案并且不使用 HTML5 属性,您可以尝试这个。

 const download = document.getElementById("fileRequest"); download.addEventListener('click', request); function request() { window.location = 'document.docx'; }
 .dwnld-cta { border-radius: 15px 15px; width: 100px; line-height: 22px }
 <h1>Download File</h1> <button id="fileRequest" class="dwnld-cta">Download</button>

This is what finally worked for me since the file to be downloaded was determined when the page is loaded.这最终对我有用,因为要下载的文件是在加载页面时确定的。

JS to update the form's action attribute: JS 更新表单的 action 属性:

function setFormAction() {
    document.getElementById("myDownloadButtonForm").action = //some code to get the filename;
}

Calling JS to update the form's action attribute:调用 JS 更新表单的 action 属性:

<body onLoad="setFormAction();">

Form tag with the submit button:带有提交按钮的表单标签:

<form method="get" id="myDownloadButtonForm" action="">
    Click to open document:  
    <button type="submit">Open Document</button>
</form>

The following did NOT work:以下没有工作:

<form method="get" id="myDownloadButtonForm" action="javascript:someFunctionToReturnFileName();">

Anywhere between your <body> and </body> tags, put in a button using the below code:<body></body>标签之间的任何地方,使用以下代码放入一个按钮:

<button>
    <a href="file.doc" download>Click to Download!</a>
</button>

This is sure to work!这肯定有效!

If you can't use form, another approach with downloadjs fit nice.如果您不能使用表单,则使用downloadjs 的另一种方法很适合。 Downloadjs use blob and html 5 file API under the hood: Downloadjs 在后台使用 blob 和 html 5 文件 API:

<div onClick=(()=>{downloadjs(url, filename)})/>

*it's jsx/react syntax, but can be used in pure html *它是 jsx/react 语法,但可以在纯 html 中使用

In my original answer, I offered a work around that does not work any longer: If the file to be downloaded is not on the same server, the attribute download does not work.在我的原始答案中,我提供了一个不再起作用的解决方法:如果要下载的文件不在同一台服务器上,则属性下载不起作用。 The problem is that the attribute download does only work when the file to be downloaded is on the same server of the tab.问题是属性下载仅在要下载的文件位于选项卡的同一服务器上时才有效。 Others have faced this problem too and the problem is extensively covered at Chrome Download Attribute not working .其他人也遇到了这个问题,这个问题在Chrome 下载属性不工作中得到了广泛的介绍。

Original answer:原答案:

There is a difference between loading a file and downloading a file.加载文件和下载文件是有区别的。 The following html code loads a file:以下 html 代码加载一个文件:

<a href="http://www.fbi.gov/top-secret.pdf">loading on the same tab</a>

After clicking on this link, your current tab will be replaced with the pdf-file that can then be downloaded.单击此链接后,您当前的选项卡将替换为可以下载的 pdf 文件。 On right-clicking on this link, you can choose the menu item save link as for downloading the file directly.右键单击该链接,您可以选择菜单项保存链接,直接下载文件。 If you wish to obtain a save as dialog on clicking on such a link, you might want to take the following code:如果您希望在单击此类链接时获得另存为对话框,您可能需要使用以下代码:

<a href="http://www.fbi.gov/top-secret.pdf?download=1">save as...</a>

Your browser will download this file immediately if you choose to use a download directory in your options.如果您在选项中选择使用下载目录,您的浏览器将立即下载此文件。 Otherwise, your browser will be offering a save as-dialog.否则,您的浏览器将提供另存为对话框。

You can also choose a button for downloading:您还可以选择一个按钮进行下载:

<button type="submit" onclick="window.open('http://www.fbi.gov/top-secret.pdf?download=1')">
    save as...
</button>

If you wish to load the link on a new tab, you take如果您希望在新选项卡上加载链接,您可以

<a href="http://www.fbi.gov/top-secret.pdf" target="_blank">loading on a new tab</a>

A form element does not heed the directive ?download=1 .表单元素不注意指令?download=1 It only heeds the directive target="_blank" :它只注意指令target="_blank"

<form method="get" action="http://www.fbi.gov/top-secret.pdf" target="_blank">
    <button type="submit">loading on a new tab</button>
</form>

Hello I just include the word 'download' and works well.您好,我只包含“下载”这个词并且效果很好。

<a href="file.pdf" download>Download</a>

So in javascript you can use the follow:因此,在 javascript 中,您可以使用以下内容:

function onStartedDownload(id) {
  console.log(`Started downloading: ${id}`);
}

function onFailed(error) {
  console.log(`Download failed: ${error}`);
}

var downloadUrl = "https://example.org/image.png";

var downloading = browser.downloads.download({
  url : downloadUrl,
  filename : 'my-image-again.png',
  conflictAction : 'uniquify'
});

downloading.then(onStartedDownload, onFailed);

This is crazy but I don't know how to do this, and because of how common the words are, it's hard to find what I need on search engines.这太疯狂了,但是我不知道该怎么做,而且由于这些单词很常见,因此很难在搜索引擎上找到我需要的东西。 I'm thinking this should be an easy one to answer.我认为这应该很容易回答。

I want a simple file download, that would do the same as this:我想要一个简单的文件下载,该操作与此相同:

<a href="file.doc">Download!</a>

But I want to use an HTML button, eg either of these:但是我想使用HTML按钮,例如以下任一按钮:

<input type="button" value="Download!">
<button>Download!</button>

Likewise, is it possible to trigger a simple download via JavaScript?同样,是否可以通过JavaScript触发简单下载?

$("#fileRequest").click(function(){ /* code to download? */ });

I'm definitely not looking for a way to create an anchor that looks like a button, use any back-end scripts, or mess with server headers or mime types.我绝对不是在寻找一种创建类似于按钮的锚,使用任何后端脚本或与服务器标头或mime类型混淆的方法。

<a href="file.doc"><button>Download!</button></a>

按钮和text-decoration的最简单方法之一将有助于更改或删除链接的文本装饰。

In my testing the following works for all file types and browsers as long as you use a relative link:在我的测试中,只要您使用相对链接,以下内容适用于所有文件类型和浏览器:

<a href="/assets/hello.txt" download="my_file.txt"><button>Download 2</button></a>
  • /assets/hello.txt is just a relative path on my site. /assets/hello.txt只是我网站上的相对路径。 Change it to your own relative path.将其更改为您自己的相对路径。
  • my_file.txt is the name you want the file to be called when it is downloaded. my_file.txt是您希望文件在下载时调用的名称。

Explanation解释

I noticed there were comments under a lot of the answers that said the browser would just try to open the file itself rather than downloading it depending on the file type.我注意到很多答案下都有评论说浏览器只会尝试打开文件本身而不是根据文件类型下载它。 I discovered this to be true.我发现这是真的。

I made two buttons to test it out using two different methods:我制作了两个按钮来使用两种不同的方法对其进行测试:

在此处输入图片说明

<button onclick="window.location.href='/assets/hello.txt';">Download 1</button>

<a href="/assets/hello.txt" download="my_file.txt"><button>Download 2</button></a>

Notes :注意事项

  • Button 1 opened the text file in a new browser tab.按钮 1 在新的浏览器选项卡中打开文本文件。 However, Button 1 would download the file for file types that it couldn't open itself (for example, .apk files).但是,按钮 1下载无法自行打开的文件类型的文件(例如,.apk 文件)。
  • Button 2 downloaded the text file.按钮 2 下载了文本文件。 However, Button 2 only downloaded the file if the path was relative.但是,按钮 2 仅在路径是相对的情况下才下载文件。 When I changed the path to an absolute path, then the browser opened it in a new tab.当我将路径更改为绝对路径时,浏览器在新选项卡中将其打开。

I tested this on Firefox, Safari, and Chrome.我在 Firefox、Safari 和 Chrome 上对此进行了测试。

Not really an answer to the original question but it may help others which face similar situations as myself.不是对原始问题的真正答案,但它可能会帮助与我面临类似情况的其他人。

If the file you want to download is not hosted on the same origin but you want to be able to download it, you can do that with the Content-Disposition header .如果您要下载的文件不在同一来源上托管,但您希望能够下载它,则可以使用Content-Disposition 标头来实现 Make sure the server includes the header when responding to requests of the file.确保服务器在响应文件请求时包含标头。

Setting a value like Content-Disposition: attachment will ensure that the file will be downloaded instead of viewed in the browser.设置一个像Content-Disposition: attachment这样的值将确保文件将被下载而不是在浏览器中查看。

A simple <a href="http://www.notMyOrigin.com/file.txt">Download</a> pointing to your file should download it in this case.在这种情况下,一个简单的<a href="http://www.notMyOrigin.com/file.txt">Download</a>指向您的文件就可以下载它。

If you want如果你想

<a href="path_to_file" download="proposed_file_name">Download</a>

for the ability to download files that would be rendered by the browser otherwise, But still want a neat javascript function to use in a button;为了能够下载将由浏览器呈现的文件,但仍然希望在按钮中使用简洁的 javascript 函数; you can have an invisible link in html and click it in javascript.您可以在 html 中有一个不可见的链接,然后在 javascript 中单击它。

 function download_file() { document.getElementById("my_download").click() }
 <a id="my_download" href="path_to_file" download="file_name" style="display:none;"></a> <button onClick="download_file()">Download!!!</button>

all you need to do is add Download after the file name which you have entered:您需要做的就是在您输入的文件名之后添加下载:

Before:前:

<a href="file.doc">Download!</a>

After

<a href="file.doc" Download >Download!</a>

Make sure the download is written with a capital letter otherwise it's not gonna work.确保下载用大写字母书写,否则将无法正常工作。

For the react users out there, I think this is a pretty clean way to go about it:对于那里的反应用户,我认为这是 go 关于它的一种非常干净的方法:

import React, {useRef} from 'react';

const DlButton = ({link}) => {
    const dlRef = useRef();
    const dlHandler = () => dlRef.current.click();

    return (
        <div>
          <button type="button" onClick={dlHandler}> 
              Download File
          </button>
          <a href={link} ref={dlRef}/>
        </div>
    );
}

Basically you create a link with no content (won't be viewed by user).基本上,您创建一个没有内容的链接(用户不会查看)。 Then you simply click that link when the user clicks the button.然后,当用户单击按钮时,您只需单击该链接。

Another way of doing in case you have a complex URL such as file.doc?foo=bar&jon=doe is to add hidden field inside the form如果您有一个复杂的 URL,例如file.doc?foo=bar&jon=doe另一种方法是在表单中添加隐藏字段

<form method="get" action="file.doc">
  <input type="hidden" name="foo" value="bar" />
  <input type="hidden" name="john" value="doe" />
  <button type="submit">Download Now</button>
</form>

inspired on @Cfreak answer which is not complete灵感来自不完整的@Cfreak 答案

The solution I have come up with is that you can use download attribute in anchor tag but it will only work if your html file is on the server.我想出的解决方案是您可以在锚标记中使用下载属性,但只有当您的 html 文件在服务器上时它才有效。 but you may have a question like while designing a simple html page how can we check that for that you can use VS code live server or bracket live server and you will see your download attribute will work but if you will try to open it simply by just double clicking html page it open the file instead of downloading it.但是您可能会遇到这样的问题,例如在设计一个简单的 html 页面时,我们如何检查您是否可以使用 VS 代码实时服务器或支架实时服务器,您将看到您的下载属性将起作用,但是如果您尝试通过以下方式打开它只需双击 html 页面即可打开文件而不是下载文件。 conclusion: attribute download in anchor tag only works if your html file is no server.结论:锚标记中的属性下载仅在您的 html 文件不是服务器时才有效。

This is crazy but I don't know how to do this, and because of how common the words are, it's hard to find what I need on search engines.这太疯狂了,但是我不知道该怎么做,而且由于这些单词很常见,因此很难在搜索引擎上找到我需要的东西。 I'm thinking this should be an easy one to answer.我认为这应该很容易回答。

I want a simple file download, that would do the same as this:我想要一个简单的文件下载,该操作与此相同:

<a href="file.doc">Download!</a>

But I want to use an HTML button, eg either of these:但是我想使用HTML按钮,例如以下任一按钮:

<input type="button" value="Download!">
<button>Download!</button>

Likewise, is it possible to trigger a simple download via JavaScript?同样,是否可以通过JavaScript触发简单下载?

$("#fileRequest").click(function(){ /* code to download? */ });

I'm definitely not looking for a way to create an anchor that looks like a button, use any back-end scripts, or mess with server headers or mime types.我绝对不是在寻找一种创建类似于按钮的锚,使用任何后端脚本或与服务器标头或mime类型混淆的方法。

你可以简单地使用:

<form action="/file.doc" align="center"> <input type="submit" id="custom-buttons" value="Click Here To Download" /> </form>

For me ading button instead of anchor text works really well.对我来说,广告按钮而不是锚文本效果很好。

<a href="file.doc"><button>Download!</button></a>

It might not be ok by most rules, but it looks pretty good.根据大多数规则,这可能不太好,但看起来不错。

如果您使用<a>标记,请不要忘记使用通向该文件的整个 url -- 即:

<a href="http://www.example.com/folder1/file.doc">Download</a>

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 单击按钮而不是打开新选项卡(HTML 或 JavaScript)时如何触发文件下载 - How to trigger a file download when clicking an button instead opening a new tab (HTML or JavaScript) 单击 HTML 按钮时如何触发带有文本区域内容的文件下载 - How to trigger a file download with text area content when clicking an HTML button <a>在现代浏览器中</a>单击html <a>标记或javascript</a>时如何触发文件下载 - How to trigger a file download when clicking an html <a> tag or javascript in a modern browser 单击 HTML 链接<a>到其他网站</a>时如何触发文件下载 - How to trigger a file download when clicking an HTML Link <a> to other website 如何在不单击javascript中的按钮的情况下触发事件 - How to trigger an event without clicking the button in javascript 单击 html 中的按钮后,如何从 javascript function 写入文件 - How to write to a file from a javascript function after clicking on a button in html 如何在 html 页面上点击提交下载文件? - How to Download file on clicking submit on an html page? 按钮未单击 HTML 和 JavaScript - Button not clicking in HTML and JavaScript 单击按钮时会加载 javascript 文件 - A button when clicking on it loads a javascript file 如何在使用JavaScript单击按钮时更改文件名并下载 - How to change a file name and download it when a button is clicked using JavaScript
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM