如何使用HTML/JavaScript强制下载文件?

11

我有一个链接,如果用户点击它,我需要做2件事情:

  • 向用户发送适当的HTTP响应(尤其是带有Content-Type: video/mp4
  • 并且一个视频文件将自动开始下载。

我已经在PHP中看到了类似的东西,但只用HTML/JavaScript是否可能?

4个回答

45

3

自动的结果很大程度上取决于浏览器及其选项。但是,您可以通过响应中的Content-Disposition头告诉浏览器您希望发生什么(然后它将与用户进行双重检查)。例如,将其设置为attachment;filename=blah.mp4将在大多数浏览器上邀请用户下载它(使用该文件名),即使通常浏览器会尝试在其自己的界面中显示/播放内容。有关详细信息,请参见链接。(对于mp4文件,下载可能是默认设置,但这取决于用户;当提供HTML文件的下载链接时,我认为这很有用。)

如果您不使用服务器端脚本(正如您所说的那样),则可以通过配置在Web服务器中设置标头。例如,对于这些视频文件的URL,您可以使用Apache规则并使用Header指令


(这不是-或者至少曾经不是-一个重复的答案。[我讨厌重复的答案。] 我发布关于Content-Disposition的答案之后,David编辑了他的答案以包括它。) - T.J. Crowder
@David:我应该表明我并不是在批评你。改进自己的答案是完全可以接受的。只是提醒一下,以防有人认为这是重复回答。 :-) - T.J. Crowder

2
不,这是不可能的(至少对于限制在客户端JavaScript值的情况而言)。
如果你想覆盖浏览器处理HTTP资源的默认行为,你需要使用HTTP头。如果你想正确地实现它,使用content-disposition头部(带有attachment值)。
你可以使用服务器端JavaScript或几乎任何其他服务器端环境来设置此头部。

1

发现了一种可靠的方法,可以使用库Axios强制下载

<script src=
"https://cdnjs.cloudflare.com/ajax/libs/axios/0.19.2/axios.min.js"></script>
<button onclick="download()">Download</button>
<script>
    let downloadUrl  = 'https://example.com/image.jpg';
    let downloadName = 'image.jpg';
    function download(){
        axios({
            url: downloadUrl,
            method:'GET',
            responseType: 'blob'
        })
        .then((response) => {
            const url = window.URL.createObjectURL(new Blob([response.data]));
            const link = document.createElement('a');
            link.href = url;
            link.setAttribute('download', downloadName);
            document.body.appendChild(link);
            link.click();
        });
    }        
</script>

我在Firefox中遇到了以下错误:跨域请求被阻止:同源策略不允许读取远程资源... - Melebius

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接