您的位置 首页 java

前后端开发文件下载

文件下载

1.环境

前端

Vue3

PrimeVUE

后端

Python

FastAPI

2.背景

在一般情况下,文件下载是不需要封装的,尤其是在写代码入门阶段,将文件存储在磁盘上,然后,直接写个 url 就可以下载文件的。

但是,由于现在 微服务 的使用,文件数据的共享,所以需要对文件下载的前后端都进行封装,后端从 MongoDB 中读取文件并返回,前端需要携带令牌来下载文件。

3.后端文件下载源代码

 # 下载文件
@router.get(path='/download_file/{oid}')
async def download_file(oid: str=Path(...), current_usr: dict = Depends(find_current_usr)):
    fileContent: bytes = None
    with MongoClient(settings.MONGO_HOST, settings.MONGO_PORT) as connect:
        filedb = connect.filedb
        mgfs = GridFS(filedb)
        out = mgfs.get(ObjectId(oid))
        logger.info('Download file {0} by {1}'.format(out.filename, current_usr['name']))
        fileContent = out.read()

    async def read_data():
        yield fileContent

    return  Streaming Response(content=read_data())


# 图片Base64字符串
@router.get(path='/download_base64/{oid}')
def base64image(oid: str=Path(...), current_usr: dict = Depends(find_current_usr)):
    res = {'base64': ''}

    with MongoClient(settings.MONGO_HOST, settings.MONGO_PORT) as connect:
        filedb = connect.filedb
        mgfs = GridFS(filedb)
        out = mgfs.get(ObjectId(oid))
        logger.info('Download file {0} by {1}'.format(out.filename, current_usr['name']))

        fileName = out.filename
        extName = fileName.split('.')[-1]
        base64Data = codecs.encode(out.read(), 'base64')

        res['base64'] = "data:image/%s;base64,%s" % (extName, base64Data. decode ('utf-8'))
    return res  

以上代码提供了文件下载和Base64图片下载。

4.前端文件下载封装

由于前端需要在下载时携带令牌,所以需要将下载文件的操作封装为统一的函数,代码如下:

 // 文件下载
const downloadConfig = {
  baseURL: '',
  timeout: 60000,
  headers: {
    'Content-Type': 'application/json'
  },
  responseType:'blob' // 接收类型: blob
}

const getResource = (oid) => {
  let _id = loading()
  // eslint-disable-next-line
  const promise = new Promise((resolve, reject) => {
    downloadConfig.headers['Authorization'] =
        localStorage.getItem('token_type') + ' ' + localStorage.getItem('access_token')

    axios.get(
        '/qycommon_api/download/download_file/' + oid,
        downloadConfig
    ).then((response) => {
      loaded(_id)
      resolve(response)
    }).catch((error) => {
      loaded(_id)
      console.log(error)
      // 对error中的数据进行处理
      let status = error.response.status
      let txt = errorToString(error)
      // 弹出错误信息
      if (status === 401) {
        swal({
          title: status.toString(),
          text: txt,
          icon: 'error',
          button: "确定",
        }).then((value) => {
          console.log(value)
          window.top.location.href = '/index.html'
        })
      } else {
        swal(status.toString(), txt, 'error')
      }
      // reject(error)
    })
  })

  return promise
}

// 图片下载 base64
const base64Config = {
  baseURL: '',
  timeout: 60000,
  headers: {
    'Content-Type': 'application/json'
  },
  responseType: 'json'
}

const getBase64 = (oid) => {
  let _id = loading()
  // eslint-disable-next-line
  const promise = new Promise((resolve, reject) => {
    base64Config.headers['Authorization'] =
        localStorage.getItem('token_type') + ' ' + localStorage.getItem('access_token')

    axios.get(
        '/qycommon_api/download/download_base64/' + oid,
        base64Config
    ).then((response) => {
      loaded(_id)
      resolve(response)
    }).catch((error) => {
      loaded(_id)
      console.log(error)
      // 对error中的数据进行处理
      let status = error.response.status
      let txt = errorToString(error)
      // 弹出错误信息
      if (status === 401) {
        swal({
          title: status.toString(),
          text: txt,
          icon: 'error',
          button: "确定",
        }).then((value) => {
          console.log(value)
          window.top.location.href = '/index.html'
        })
      } else {
        swal(status.toString(), txt, 'error')
      }
      // reject(error)
    })
  })

  return promise
}  

对应于后端,前端的文件下载封装也设计了两个函数:文件下载和Base64图片下载。

5.前端文件下载代码

     // 下载头像文件
    download_avatar_file (oid) {
      // getResource(oid).then((response) => {
      //  this.avatar_file_data = window.URL.createObjectURL(response.data)
      // })
      getBase64(oid).then((response) => {
        this.avatar_file_data = response.data.base64
      })
    },  

对于下载的文件如果需要显示在页面上,则需要使用 window.URL.createObjectURL() 函数;

如果是 Base64 图像,直接将返回的 Base64 字符串赋值给相应的变量即可。

文章来源:智云一二三科技

文章标题:前后端开发文件下载

文章地址:https://www.zhihuclub.com/191575.shtml

关于作者: 智云科技

热门文章

网站地图