【问题标题】:Vue/HTML/JS how to download a file to browser using the download tagVue/HTML/JS 如何使用下载标签将文件下载到浏览器
【发布时间】:2019-05-15 06:54:56
【问题描述】:

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

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

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

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

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

添加 target="_blank" 并不能解决问题

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

单击上述链接时,文件将在新的浏览器选项卡中打开,我需要防止这种默认行为并在单击时强制下载。假设 HTML 5 标签“下载”似乎无法解决这个问题。

Chrome 最近弃用了用于跨域下载的下载标签表单。 vue 是否有一个修饰符来防止这个默认值?有没有其他方法可以用 javascript 或 html 下载文件?

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

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

谢谢。

【问题讨论】:

  • 这与你的服务器代码有关,而不是 vue 本身。尝试在服务器端添加 developer.mozilla.org/en-US/docs/Web/HTTP/Headers/… Content-Disposition 标头,以便您获得官方规范而不是专有标记扩展的支持。
  • 该 url 是一个包含图像的公共 url,例如 googledrive 公共链接图像。遗憾的是我无法控制服务器及其标头,我只希望用户将文件下载到浏览器而不在新选项卡中打开它。
  • AFAIK,当前唯一可用的解决方案是您提到的“hacky”解决方案。
  • 你好托尼,谢谢,是的,我也在寻找一个 vue 特定的例子,因为 vue 有很多防止默认的方法,我希望它可以做到.. 但在这种情况下并没有lars 的以下回答为我解决了这个问题。

标签: html vue.js arraybuffer


【解决方案1】:

除了接受的答案外,还可以通过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);
        })
}

【讨论】:

    【解决方案2】:

    我正在使用 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');
    

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

    【讨论】:

      【解决方案3】:

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

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

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

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

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

      要做到这一点服务器端取决于你使用的服务器。

      【讨论】:

      • 添加最后一行我遇到了 CORS 问题。
      • 还不错,但是在使用这个的时候会有一个难看的闪烁(可能是因为一个新窗口正在打开然后很快关闭)。
      【解决方案4】:

      您可以将文件作为 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 类型是硬连线的。

      【讨论】:

      • 谢谢,您的回答解决了我的问题,因为您使用了 VUE 而其他答案没有。
      • 导致cors问题
      • 如果您遇到 CORS 问题,请确保您有权使用 JavaScript 访问源代码。参考:developer.mozilla.org/nl/docs/Web/HTTP/CORS
      • 如果您愿意使用外部库,file-saver 无需创建链接元素。只需使用import { saveAs } from 'file-saver'; 导入并使用saveAs(blob, "filename.ext"); 调用
      • 这种方法对于大文件来说是不好的做法,因为它将整个文件加载到浏览器的内存中
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2022-06-16
      • 2020-10-20
      • 2018-12-11
      • 2012-07-18
      • 2018-08-03
      • 1970-01-01
      • 2011-09-25
      相关资源
      最近更新 更多