Vue / HTML / JS如何使用下载标签将文件下载到浏览器

Ric*_*y-U 8 html5 arraybuffer vue.js

这个问题与提供的其他答案不同,因为我的问题集中在VUE上,并且VUE是否也有防止默认方法的方法。

这个问题更特定于HTML 5“下载”以及:href的VUE绑定,以及为什么它不能阻止默认浏览器在新选项卡中打开文件的行为。

预期的行为:将文件下载到浏览器

实际行为:在新选项卡中打开文件

例外:在新选项卡中仅打开图像,pdf和浏览器兼容的文件,其他文件(如.exe)正常下载-为什么这样做,可以在html中更改此行为吗?

添加target =“ _ blank”不能解决问题

<a :href="downloadById(item.url)" download>Download</a>
Run Code Online (Sandbox Code Playgroud)

单击上面的链接后,将在新的浏览器选项卡中打开文件,我需要防止这种默认行为,并在单击后强制下载。HTML 5标记“下载”被认为可以解决此问题,但似乎不起作用。

Chrome最近不推荐使用跨域下载的下载标签表单。vue是否有修饰符来防止此默认设置?还有其他方法可以使用javascript或html下载文件吗?

一个建议的解决方案是将URL读取为arrayBuffer,然后在DOM中创建一个新的blob,然后创建一个anchor元素,然后单击它。。但这似乎很难强制下载文件。

我确信他们一定是一个更干净的解决方案,可以从URL下载文件,这是一个小问题,希望有一个简单的解决方案。

谢谢。

Lar*_*eck 15

避免CORS问题的一种较简单的方法是通过XHR请求获取文件并将文件作为blob提供:

模板

<a
  :href="item.url"
  v-text="item.label"
  @click.prevent="downloadItem(item)" />
Run Code Online (Sandbox Code Playgroud)

Vue

methods: {
  downloadItem ({ url, label }) {
    Axios.get(url, { responseType: 'blob' })
      .then(({ data }) => {
        const blob = new Blob([data], { type: 'application/pdf' })
        const link = document.createElement('a')
        link.href = window.URL.createObjectURL(blob)
        link.download = label
        link.click()
      }).catch(error => console.error(error))
    })
  }
}
Run Code Online (Sandbox Code Playgroud)

我以Axios为例,但您应该可以使用所需的任何lib。还要注意,为简化起见,blob的mime类型和下载的名称都是硬连线的。

  • 对于大文件,这种方法是不好的做法,因为它将整个文件加载到浏览器的内存中 (7认同)
  • 这会导致cors问题 (2认同)
  • 如果您遇到 CORS 问题,请确保您有权使用 JavaScript 访问源。参考:https://developer.mozilla.org/nl/docs/Web/HTTP/CORS (2认同)
  • 如果您愿意使用外部库,[file-saver](https://www.npmjs.com/package/file-saver) 无需创建链接元素。只需使用 import { saveAs } from 'file-saver';` 导入并使用 saveAs(blob, "filename.ext");` 调用即可 (2认同)

Eme*_*bah 8

我正在使用 Laravel 和 Vue。使用https://github.com/maatwebsite/Laravel-Excel

在 Laravel 路线中

在下载的控制器方法中,我返回https://docs.laravel-excel.com/3.1/exports/exportables.html -> 负责实例

Route::get('users/download', 'userController@download')
->name('users.download');
Run Code Online (Sandbox Code Playgroud)

在我的Vue中:

<!--
  - Page Header Template
  -->
<template>
    <div class="page-header">
        <button 
            v-if="$is_admin"
            class="button secondary download" @click="download">Download
        </button>
    </div>
</template>

<script>
    export default {

        methods: {
            download () {
                const url = '/users/download';
                window.location.href = url;
            }
        },
    };
</script>
Run Code Online (Sandbox Code Playgroud)