其他分享
首页 > 其他分享> > abpvnext中Blob存储系统和vue前端通过Blob下载

abpvnext中Blob存储系统和vue前端通过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