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

Vue/HTML/JS how to download a file to browser using the download tag

这个问题与提供的其他答案不同,因为我的问题是针对VUE的,如果VUE也有阻止默认方法的方法。

这个问题更具体地针对 HTML 5 "download" 以及 :href 的 VUE 绑定以及为什么它不能阻止浏览器在新文件中打开文件的默认行为选项卡

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

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

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

添加 target="_blank" 没有解决问题

<a :href="downloadById(item.url)" download>Download</a>

单击上面的 link 时,文件将在新的浏览器选项卡中打开,我需要防止这种默认行为并在单击时强制下载。 HTML 5 标签 "download" 是用来解决这个问题的,但似乎不起作用。

Chrome 最近弃用了用于跨域下载的下载标签形式。 vue 是否有修饰符来防止这种默认情况?在 javascript 或 html 中还有其他方法可以下载文件吗?

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

我相信他们一定是从 URL 下载文件的更简洁的解决方案,这是一个微不足道的问题,希望有一个简单的解决方案。

谢谢。

您可以将文件作为 blob 获取并以相同的方式提供,不会有导致 CORS 问题的请求。

模板

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

Vue

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

注意:我在示例中使用了 Axios,但这不是必需的,为了简单起见,blob 的 mime 类型是硬连线的。

如果您希望浏览器处理下载而不是处理 JavaScript 中的下载,您需要使用 window.open:

window.open("<insert URL here>")

这提供了更好的用户体验 IMO,但在尝试访问 authorization-protected 内容时设置起来很棘手。为此,您需要将授权存储在 cookie 中,而不是依赖于将授权 header 存储在浏览器的本地存储中。这将需要配置您的服务器和客户端以这种方式进行身份验证。

要在客户端执行此操作,请确保 axios 知道存储凭据:

import axios from 'axios'
axios.defaults.withCredentials = true

要在服务器端执行此操作取决于您使用的服务器。

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

在Laravel路线

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

Route::get('users/download', 'userController@download')
->name('users.download');

在我的 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>

除了已接受的答案外,还可以通过 file-saver 包轻松下载文件。

npm install file-saver --save
npm install @types/file-saver --save

然后:

import {saveAs} from 'file-saver';
downloadItem(url) {
    axios
        .get(url, {responseType: 'blob'})
        .then(response => {
            saveAs(response.data, 'downloaded-file.pdf);
        })
}