ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

abpvnext中Blob存储系统和vue前端通过Blob下载

2022-07-01 15:00:53  阅读:136  来源: 互联网

标签:存储 vue abpvnext BLOB blob IBlobContainer 下载 Blob


VUE中Blob对象

我们都知道下载文件有一种很简单的方法:window.open(url),但是window.open(url)只是一个纯粹的访问下载文件的链接,并不能满足所有下载文件的需求。

1.前端下载文件有时候会根据权限去下载(需要获取登录的token)

2.有时后端提供的是post/get请求的接口

3.自定义文件名

由于VUE框架安全性的要求,类似window.open(url),window.location.href = url等方式都会被vue响应拦截器过滤掉,并报不安全下载!这时就需要用到blob啦!

了解vue中blob

Vue中的Blob 对象表示一个不可变、原始数据的类文件对象。它的数据可以按文本或二进制的格式进行读取,也可以转换成 ReadableStream 来用于数据操作。

 

 

 

File 接口基于Blob,继承了 blob 的功能并将其扩展使其支持用户系统上的文件。要从其他非blob对象和数据构造一个 Blob,请使用 Blob() 构造函数。要创建一个 blob 数据的子集 blob,请使用 slice() 方法。

 

 

 

 

  

VUE配置Blob请求

要在VUE中请求Blob类型的数据,必须请求中要配置 responseType: 'Blob' // ArrayBuffer/ArrayBufferView/DOMString 都可以。

 

 

 

如果不指定blob类型,下载的文件例如word就会报如下错误(困扰了好久的):

 

 

 

在vue-element-admim中封装一个带blob请求类型的Get访问:

 

 

 

方法一:a标签下载(get请求)

1. 在接口返回的结果中要 new 一个 Blob()

const blob = new Blob([res], {type: 'application/octet-stream'})

第一个参数:是一个由ArrayBuffer, ArrayBufferView, Blob, DOMString 等对象构成的 Array ,或者其他类似对象的混合体,它将会被放进 Blob。DOMStrings会被编码为UTF-8。

第二个参数:默认值为 "",它代表了将会被放入到blob中的数组内容的MIME类型。

2. 使用 URL.createObjectURL(blob) 生成一个 URL

let url = URL.createObjectURL(blob)

3. 动态创建 a 标签并执行 click 事件完成下载!

示例代码:支持IE10+以上版本,chrome/firefox浏览器,其他浏览器待测试,主流的三种都支持下载!

 

 

 

 

方法二:插件file-saver下载

插件下载不用考虑浏览器,IE和谷歌等都测试过了,不用像方法一,做特殊的处理。

一,执行以下命令进行安装:

npm install file-saver –save

二,语法:

saveAs()从文件保存器导入

import { saveAs } from 'file-saver';

FileSaver saveAs(Blob/File/Url, optional DOMString filename, optional Object { autoBom })

传递{ autoBom: true }如果你想FileSaver.js自动提供Unicode文本编码提示(:见字节顺序标记)。请注意,只有在您的Blob类型已charset=utf-8设置的情况下才能执行此操作。

三,例子

l 使用保存文字 require()

var FileSaver = require('file-saver');

var blob = new Blob(["Hello, world!"], {type: "text/plain;charset=utf-8"});

FileSaver.saveAs(blob, "hello world.txt");

l 储存文字

var blob = new Blob(["Hello, world!"], {type: "text/plain;charset=utf-8"});

FileSaver.saveAs(blob, "hello world.txt");

l 保存网址

FileSaver.saveAs("https://httpbin.org/image", "image.jpg");

在相同来源内使用URL只会使用a[download]。否则,它将首先检查它是否支持带有同步头请求的cors标头。如果是这样,它将下载数据并使用Blob URL保存。如果没有,它将尝试使用下载它a[download]。

标准的W3C File API Blob接口并非在所有浏览器中都可用。 Blob.js是Blob解决此问题的跨浏览器实现。

l 保存画布

var canvas = document.getElementById("my-canvas");

canvas.toBlob(function(blob) {

    saveAs(blob, "pretty image.png");

});

注意:标准HTML5 canvas.toBlob()方法并非在所有浏览器中都可用。 canvas-toBlob.js是一个跨浏览器canvas.toBlob(),可以对此进行填充。

l 保存文件

您可以保存File构造函数而无需指定文件名。如果文件本身已经包含名称,则有很多方法可以获取文件实例(从存储,文件输入,新构造函数,剪贴板事件)。如果仍要更改名称,则可以在第二个参数中更改它。

// Note: Ie and Edge don't support the new File constructor,

// so it's better to construct blobs and use saveAs(blob, filename)

var file = new File(["Hello, world!"], "hello world.txt", {type: "text/plain;charset=utf-8"});

FileSaver.saveAs(file);

框架中封装的代码:

 

 

 

调用:

 

 

  

效果图

带token认证下载,提高了下载的安全性,没有token是无权下载的

IE下载

 

 

 

谷歌下载

 

 

 

打开下载的文件:

 

 

 

文件上传,可上传单个或批量上传(限制最多5个)、可拖拽上传:

 

 

 

文件文件与图片文件,其中图片文件可进行预览操作(放大,缩小、旋转和下载):

 

 

 

 vue中axios中设置blob调用,重要的设置是responseType: 'blob'

 BlobPosts(url, params) {
    var param = new FormData()
    return new Promise((resolve, reject) => {
      axios({
        url: url,
        method: 'post',
        data: params
        , responseType: 'blob'
        , headers: {
          'Content-Type': 'application/json;charset=UTF-8'
        }

      })
        .then(response => {
          resolve(response.data)
        }, err => {
          Message({
            message: err.error.details,
            type: 'error',
            duration: 5 * 1000
          })
          reject(err)
        })
        .catch((error) => {
          reject(error)
        })
    })
  },
  BolbGets(url, params) {
    return new Promise((resolve, reject) => {
      axios({
        url: url,
        method: 'get',
        headers: {
          'Authorization': 'Bearer ' + getToken(),
          'Content-Type': 'application/json;charset=UTF-8'
        },
        params: params,
        responseType: "blob"
      })
        .then(response => {
          resolve(response.data)
        }, err => {
          Message({
            message: err.error.message,
            type: 'error',
            duration: 5 * 1000
          })
          reject(err)
        })
        .catch((error) => {
          reject(error)
        })
    })
  },

 

 

Abpvnext中Blob存储系统

BLOB 系统,主要用于存储大型二进制文件。ABP 抽象了一套通用的 BLOB 体系,开发人员在存储或读取二进制文件时,可以忽略具体实现,直接使用 IBlobContainer 或 IBlobContainer<T> 进行操作。

了解BLOB

通常将文件内容存储在应用程序中并根据需要读取这些文件内容. 不仅是文件你可能还需要将各种类型的BLOB(大型二进制对象)保存到存储中. 例如你可能要保存用户个人资料图片.

BLOB通常是一个字节数组. 有很多地方可以存储BLOB项. 可以选择将其存储在本地文件系统中,共享数据库中或Azure BLOB存储中.

ABP框架为BLOB提供了抽象,并提供了一些可以轻松集成到的预构建存储提供程序. 抽象有一些好处;

l 你可以通过几行配置轻松的集成你喜欢的BLOB存储提供程序.

l 你可以轻松的更改BLOB存储,而不用改变你的应用程序代码.

l 如果你想创建可重用的应用程序模块,无需假设BLOB的存储方式.

 

BLOB安装

本项目中手动安装的,即项目中安装 Volo.Abp.BlobStoring NuGet包然后将[DependsOn(typeof(AbpBlobStoringModule))]添加到项目内的ABP模块类中。

 

 

 

 

BLOB 存储提供程序

ABP框架已经有以下存储提供程序的实现;

  1. File System:将BLOB作为标准文件存储在本地文件系统的文件夹中.
  2. Database: 将BLOB存储在数据库中.
  3. Azure: 将BLOG存储在 Azure BLOB storage中.
  4. Aliyun: 将BLOB存储在Aliyun Storage Service中.
  5. Ninio: 将BLOB存储在MinIO Object storage中.
  6. Aws: 将BLOB存储在Amazon Simple Storage Service中.

本项目中,使用Blob存储数据库提供程序,即第二种方式。

通过nuget引入Volo.Abp.BlobStoring.Database模块, 在数据库中存储对象/文件.目前支持Entity Framework Core(因此,你可以使用任何关系数据库和MongoDB).

BLOB存储数据库提供程序可以将BLOB存储在关系或非关系数据库中.

有两个数据库提供程序实现;

l Volo.Abp.BlobStoring.Database.EntityFrameworkCore 包实现EF Core, 它可以通过EF Core存储BLOB在任何支持的DBMS中.

l Volo.Abp.BlobStoring.Database.MongoDB 包实现了MongoDB.

 

手动安装

这里是此提供程序定义的所有包:

Volo.Abp.BlobStoring.Database.Domain.Shared

Volo.Abp.BlobStoring.Database.Domain

Volo.Abp.BlobStoring.Database.EntityFrameworkCore

Volo.Abp.BlobStoring.Database.MongoDB

你可以只安装 Volo.Abp.BlobStoring.Database.EntityFrameworkCore 或 Volo.Abp.BlobStoring.Database.MongoDB (根据你的偏好),因为它们依赖其他包.

安装完成后,添加 DepenedsOn 属性到相关模块.下面是由上面列出的相关NuGet包定义的模块类列表:

BlobStoringDatabaseDomainModule

BlobStoringDatabaseDomainSharedModule

BlobStoringDatabaseEntityFrameworkCoreModule

BlobStoringDatabaseMongoDbModule

如果你正在使用EF Core,还需要配置你的Migration DbContext将BLOB存储表添加到你的数据库. 在 OnModelCreating 方法中调用 builder.ConfigureBlobStoring() 扩展方法来包含到DbContext的映射. 你可以使用标准的 Add-Migration 和 Update-Database 命令在数据库中创建必要的表.

本项目中,安了Volo.Abp.BlobStoring.Database.EntityFrameworkCore,并配置Migration DbContext将BLOB存储表添加到数据库。

public DbSet<BlobData> BlobDatas { get; set; }

 

 

 

创建BLOB容器

在使用blob存储之前,我们需要创建blob容器。

看一个 ABP 的库项目,首先从他的 Module 入手,对应的 BLOB 核心库的 Module 就是 AbpBlobStoringModule 类,在其内部,只进行了两个操作,注入了 IBlobContainer 与 IBlobContainer<> 的实现。

 

 

 

说明:从上述代码可以看出来,IBlobContainer 的默认实现还是基于 BlobContainer<T> 的。那么为啥会有个泛型的 Container,从简介中可以看到 OSS 里面对应的 Bucket 其实就是一个 IBlobContainer。假如你会针对某云的多个 Bucket 进行操作,那么就需要类型化的 BlobContainer 了。

IBlobContainer 是存储和读取BLOB的主要接口. 应用程序可能有多个容器,每个容器都可以单独配置. 有一个默认容器可以通过注入 IBlobContainer 来简单使用

public interface IBlobContainer

{

    // 保存对象

    Task SaveAsync(

        string name,

        Stream stream,

        bool overrideExisting = false,

        CancellationToken cancellationToken = default

    );

    

    // 删除对象

    Task<bool> DeleteAsync(

        string name,

        CancellationToken cancellationToken = default

    );

    

    // 判断对象是否存在

    Task<bool> ExistsAsync(

        string name,

        CancellationToken cancellationToken = default

    );

    

    // 获取对象

    Task<Stream> GetAsync(

        string name,

        CancellationToken cancellationToken = default

    );

 

    // 获取对象(不存在返回 NULL)

    Task<Stream> GetOrNullAsync(

        string name,

        CancellationToken cancellationToken = default

    );

    

    //TODO: Create shortcut extension methods: GetAsArraryAsync, GetAsStringAsync(encoding) (and null versions)

}

 

在项目中创建一个名为MyFileContainer的类,只是一个用来标识容器的空类。

 

 

 

为类型化容器MyFileContainer配置文件系统提供器,这个一定要进行注册,不然在调用webapi时会报错!

 

 

 

创建应用层

在创建应用程序服务之前,我们需要创建一些由应用程序服务使用的DTO。

Vue端调用的DTO:

 

请求DTO,下载时传入的参数名:

 

 

 

 

 

用于保存BLOB:

 

 

 

接口:

 

 

 

项目集:

 

 

 

 

接下来,创建我们的应用程序服务,在BLOB容器中看到,BlobContainer<MyFileContainer>注入到应用程序服务中。 它将处理所有blob动作。

应用服务如下:

 

 

 

上述服务代码中:

l SaveBlobAsync方法使用SaveAsync IBlobContainer<MyFileContainer>的IBlobContainer<MyFileContainer>定的Blob保存到存储中。

l GetBlobAsync方法是使用GetAllBytesAsync IBlobContainer<MyFileContainer>的IBlobContainer<MyFileContainer>通过名称获取Blob内容。

创建控制器

  1. BlobFileController注入了我们之前定义的IFileAppService 。
  2. DownloadAsync用于将文件从服务器发送到客户端。
  3. 该控制器只有一个端点,该端点仅需要一个string参数,然后我们使用该参数来获取存储的blob。 如果存在blob,我们将返回File结果,以便可以开始下载过程。

 

 

 

Swagger

 

 

 

Post请求用来上传附件并保存BLOB:

 

 

 

Get请求用于获取BLOB存储,传入的参数为文件名,做为参数的文件名,用了GUID加上后缀名进行组合,保证不会有重复!

VUE前端调用

 

标签:存储,vue,abpvnext,BLOB,blob,IBlobContainer,下载,Blob
来源: https://www.cnblogs.com/netcore-vue/p/16434670.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有