页面路由跳转 - 文件 File对象数据传递

本文描述了在Vue应用中,如何在页面间安全地传递包含文件的复杂数据,包括使用query参数、JSON.stringify和base64转换,以及解决文件对象丢失的问题。作者提供了详细的步骤和示例代码,以帮助开发者理解和处理类似场景。
摘要由CSDN通过智能技术生成

需求

页面A填写完信息(填写的信息中有上传的文件)之后需要跳转到页面B签名,然后在页面B内将填写的信息(包括上传的文件)和签名图片一起调用接口上传。

主要问题点

  1. 页面A 跳转到 页面B 需要携带页面A填写的信息(包括上传的文件 fileList 以及 其中File对象)
  2. this.$router.push() 通过 query 传参 fileList(两种方法主要是用不用 JSON.parse() 处理的区别):
    2.1 文件列表 fileList 直接携带:跳转到页面B可以取到其中的 file ,【但是】页面刷新之后就没有了(详见下问题2.1演示)
    2.2 文件列表 fileList 通过 JSON.parse() 转换携带:跳转到页面B JSON.stringify() 后fileList中的 file 为空 (详见下问题2.2演示及解决)
    【最终解决】问题点2.2 演示及解决:页面A + 页面B 处理2

【注】
在这里插入图片描述

问题点2.1 演示

页面A

// 路由跳转
this.$router.push({
  path: '/sign', // 跳转到签名的路由
  query: {
    // ...
    fileList: this.fileList, // 当前页面上传的文件需要在签名页面调接口和签名的图片一起上传
  }
})

页面B

 this.fileList = this.$route.query.fileList

页面 B 直接取 $route.query 中 fileList,file对象信息存在,没有问题
在这里插入图片描述

刷新页面后出现问题:
在这里插入图片描述

问题点2.2 演示及解决

页面A

this.fileList.forEach(async item => {
  // console.log('item----', item)
  // const base64 = await this.file2DataURL(item.file) // 此处不需要
  // item.content = base64
  item.filename = item.file.name // 接口上传文件时需要文件名,否则接口会报错
})
// 路由跳转
this.$router.push({
  path: '/sign', // 跳转到签名的路由
  query: {
    // ...
    fileList: JSON.stringify(this.fileList), // 当前页面上传的文件需要在签名页面调接口和签名的图片一起上传
  }
})

页面B 处理1 - 有问题

this.fileList = JSON.parse(this.$route.query.fileList || '[]')

页面B JSON.parse(this.$route.query.fileList || '[]') 处理后,file 对象丢失
在这里插入图片描述

页面B 处理2 - 没有问题 - 最终解决办法

import { dataURLtoFile } from '@/utils/index.js'

this.fileList = JSON.parse(this.$route.query.fileList || '[]')
this.fileList.forEach(item => {
  const File = dataURLtoFile(item.content, item.filename, 'image/png') // 【主要代码 - 重点】将base64格式文件转为 file对象
  item.file = File
})

页面B 中将页面A传过来的 base64 格式文件转为 file 对象
在这里插入图片描述

@/utils/index.js

/**
 * 将 base64 转换为 file 对象
 *    dataURL:base64 格式
 *    fileName:文件名
 *    fileType:文件格式
 */
export function dataURLtoFile(dataURL, fileName, fileType) {
  const arr = dataURL.split(',')
  const mime = arr[0].match(/:(.*?);/)[1]
  const bstr = atob(arr[1])
  let n = bstr.length
  const u8arr = new Uint8Array(n)
  while (n--) {
    u8arr[n] = bstr.charCodeAt(n)
  }
  return new File([u8arr], fileName, { type: fileType || 'image/jpg' })
}

【补充】 file 对象转为 base64 文件(即 将 file 对象转为 DataURL)

以上 问题点2.2 演示及解决 - 页面A 中我的 fileList 数据中有文件的 base64 格式,就可以直接传到页面B将该 base64 转为 file 对象。
如果自己的数据中没有 base64 格式的话,需要:将 页面A 中 file 对象转为 base64 格式 → 页面A将base64数据通过路由的 query 传到页面B → 页面B 接收到base64数据 → 再将 base64 转为 file 对象

file 对象转为 base64 文件
页面A

this.fileList.forEach(async item => {
  // console.log('item----', item)
  const base64 = await this.file2DataURL(item.file) // 【主要代码】
  item.content = base64
  item.filename = item.file.name // 接口上传文件时需要文件名,否则接口会报错
})
// 路由跳转
this.$router.push({
  path: '/sign', // 跳转到签名的路由
  query: {
    // ...
    fileList: JSON.stringify(this.fileList), // 当前页面上传的文件需要在签名页面调接口和签名的图片一起上传
  }
})

// 【主要代码】file 对象转为 base64 文件(即 将 file 对象转为 DataURL)
file2DataURL(file) {
  return new Promise(resolve => {
    const reader = new FileReader()
    reader.onload = () => {
      resolve(reader.result)
    }
    reader.readAsDataURL(file)
  })
},

在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值