【Vue2】Vant2上传文件使用formData方式,base64图片转Blob再转File上传

文章目录

  • 前言
  • 一、base64转换为 Blob 对象的方法
  • 二、使用步骤
    • 1.引入工具类js
    • 2.编写formData上传方法
    • 3.api方法中的request代码
  • 三、实际操作
    • 1.html代码
    • 2.js代码
  • 总结


前言

vant2上传组件传送门
使用vant2组件中的uploader组件

<van-uploader v-model="fileList" multiple capture :after-read="afterRead" @delete="onDelete" />

提示:以下是本篇文章正文内容,下面案例可供参考

一、base64转换为 Blob 对象的方法

在utils文件夹下,创建一个工具类js,名叫base64toFile.js

// 转换为 Blob 对象的方法 (可复用)
export function base64ToBlob(base64Data) {const parts = base64Data.split(";base64,");const contentType = parts[0].split(":")[1];const raw = window.atob(parts[1]);const rawLength = raw.length;const uInt8Array = new Uint8Array(rawLength);for (let i = 0; i < rawLength; ++i) {uInt8Array[i] = raw.charCodeAt(i);}return new Blob([uInt8Array], { type: contentType });
}
// 从 base64 数据中获取文件名和 mime 类型的方法 (可复用)
export function getFilenameAndMimetypeFromBase64(base64Data) {const fileInfo = base64Data.split(';base64,')[0].substring(5).split(':');const mimeType = fileInfo[0];const filename = fileInfo[1];return [filename, mimeType];
}
/***  用法
// 将 base64 编码的文件数据转为 Blob 对象
const blob = base64ToBlob(res);
// 获取文件名和 mime 类型
const [filename, mimeType] = getFilenameAndMimetypeFromBase64(res);
// 将 Blob 对象转换为 File 对象
const file = new File([blob], filename, { type: mimeType });
// 上传文件
const formData = new FormData();
formData.append('file', file);axios.post('/api/upload', formData, {headers: {'Content-Type': 'multipart/form-data'}
}).then(response => {console.log(response.data);
}).catch(error => {console.log(error);
});*/

用法在上面代码里有,也就是后面的过程

二、使用步骤

1.引入工具类js

代码如下(示例):

import {base64ToBlob,getFilenameAndMimetypeFromBase64
} from "@/utils/base64toFile.js"

2.编写formData上传方法

src/api里面的某一个文件夹里面编写你的上传
在这里插入图片描述

代码如下(示例):

import request from '@/utils/request'
// 上传图片
export function uploadImg(data) {return request({url: '/flow/common/upload',method: 'post',headers: {'Content-Type': 'multipart/form-data'},data: data})
}

根据实际情况修改url地址,

3.api方法中的request代码

在utils工具文件夹中新建request.js

import axios from 'axios'
import errorCode from '@/utils/errorCode'
import {getToken
} from '@/utils/auth'
import {Dialog,Notify
} from 'vant';
axios.defaults.headers['Content-Type'] = 'application/json;charset=utf-8'// 创建axios实例
const service = axios.create({// axios中请求配置有baseURL选项,表示请求URL公共部分// baseURL: '/',baseURL: process.env.VUE_APP_BASE_API,// 超时timeout: 40000
})
// request拦截器
service.interceptors.request.use(config => {// 是否需要设置 tokenconst isToken = (config.headers || {}).isToken === false// config.headers['Authorization'] = sessionStorage.getItem('token') // 让每个请求携带自定义token 请根据实际情况自行修改// config.headers['token'] = sessionStorage.getItem('token') // 让每个请求携带自定义token 请根据实际情况自行修改config.headers['Authorization'] = 'Bearer ' + getToken()// get请求映射params参数if (config.method === 'get' && config.params) {let url = config.url + '?';for (const propName of Object.keys(config.params)) {const value = config.params[propName];var part = encodeURIComponent(propName) + "=";if (value !== null && typeof (value) !== "undefined") {if (typeof value === 'object') {for (const key of Object.keys(value)) {let params = propName + '[' + key + ']';var subPart = encodeURIComponent(params) + "=";url += subPart + encodeURIComponent(value[key]) + "&";}} else {url += part + encodeURIComponent(value) + "&";}}}url = url.slice(0, -1);config.params = {};config.url = url;}return config
}, error => {console.log(error)Promise.reject(error)
})
// 响应拦截器
service.interceptors.response.use(res => {// 未设置状态码则默认成功状态const code = res.data.code || 200;// 获取错误信息const msg = errorCode[code] || res.data.msg || errorCode['default']// 二进制数据则直接返回if (res.request.responseType === 'blob' || res.request.responseType === 'arraybuffer') {return res.data}if (code === 401) {return Promise.reject('无效的会话,或者会话已过期,请重新登录。')} else if (code === 402) {Dialog.alert({message: res.data.msg,confirmButtonColor: "#3478F3",}).then(() => {});return Promise.reject(new Error(msg))} else if (code === 403) {return Promise.reject(new Error(msg))} else if (code === 500) {Notify({type: 'danger',message: msg});return Promise.reject(new Error(msg))} else if (code === 601) {Notify({type: 'warning',message: msg});return Promise.reject('error')} else if (code !== 200) {Dialog({title: '错误',message: msg});return Promise.reject('error')} else {return res.data}
},error => {console.log('err' + error)let {message} = error;if (message == "Network Error") {message = "后端接口连接异常";} else if (message.includes("timeout")) {message = "系统接口请求超时";} else if (message.includes("Request failed with status code")) {message = "系统接口" + message.substr(message.length - 3) + "异常";}Notify({message: message,type: 'danger',duration: 5 * 1000,});return Promise.reject(error)}
)
export default service

request.js有许多的工具类引入,不过一般的vue项目应该都有脚手架,如果没有的,或者没见过这个request.js的,可以去翻一下若依后台管理系统的源码。这里只作示例,告知请求方法中的封装是这些代码


三、实际操作

1.html代码

<van-uploader v-model="fileList" multiple capture :after-read="afterRead" @delete="onDelete" />

2.js代码

import方法

import {base64ToBlob,getFilenameAndMimetypeFromBase64
} from "@/utils/base64.js"
import {uploadImg, // 上传拍照的图片
} from "@/api/upload.js"

data变量

fileList: [],

methods方法

afterRead(res) {// 此时可以自行将文件上传至服务器console.log(res, "file");// base64格式赋值, data:image/jpeg;base64,/9j.......const data = res.content// 将 base64 编码的文件数据转为 Blob 对象const blob = base64ToBlob(data);// 获取文件名和 mime 类型const [filename, mimeType] = getFilenameAndMimetypeFromBase64(data);// 将 Blob 对象转换为 File 对象const file = new File([blob], res.file.name, { type: mimeType });// 写入formDataconst formData = new FormData();formData.append('file', file);// 执行上传方法uploadImg(formData).then(res => {console.log(res, "上传结果", this.fileList);this.form.files.push(res.data) // 写入form参数})
},

afterRead为vant组件 上传模块的回调
它的回调参数的content是一个base64图片 data:image/jpeg;base64,/9j.......

这段代码的文件名有可能会拿不到,毕竟是base64图片文件,所以filename可以自己定义,
在这里插入图片描述

// 获取文件名和 mime 类型
const [filename, mimeType] = getFilenameAndMimetypeFromBase64(res);
// 将 Blob 对象转换为 File 对象
const file = new File([blob], filename, { type: mimeType });

总结

除了base64格式的文件,可以用formData方式上传,别的例如文档doc、pdf也可以。
只要选择文件上传,拿到的回调参数里面,有一个是file类型的,那就是这个。
把这个file添加到formData,然后也是一样的上传。
如下

<el-dialog :title="upload.title" :visible.sync="upload.open" width="400px" append-to-body><el-upload class="upload-demo" :file-list="uploadFileList" drag:on-change="getFiles" :on-remove="getFiles"action="" :auto-upload="false" multiple><i class="el-icon-upload"></i><div class="el-upload__text">将文件拖到此处,或<em>点击上传</em></div><div class="el-upload__tip" slot="tip">只能上传jpg/png文件,且不超过500kb</div></el-upload><div slot="footer" class="dialog-footer"><el-button type="primary" @click="submitFileForm">确 定</el-button><el-button @click="upload.open = false">取 消</el-button></div>
</el-dialog>
// 提交上传文件
submitFileForm() {let formData = new FormData();this.files.forEach(f => formData.append("files", f.raw))fileUpload(formData).then(res => {this.$modal.msgSuccess("上传成功")})this.upload.open = false;
},
getFiles(file, fileList) {this.files = fileList;
},

在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/1535.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

css实现元素纵向排列自动换列

块级元素在容器类纵向排列&#xff0c;当达到最大高度后自动换到下一列 <div id"main-div"><div class"item">1 一条内容一条内容一条内容一条内容一条内容一条内容一条内容一条内容一条内容一条内容一条内容一条内容一条内容一条内容一条内容…

只用一次集合遍历实现树形结构,非递归方式

一般情况下&#xff0c;我们想要实现这种无限层级的树形结构&#xff0c;都是采用递归的方式&#xff0c;但是递归比较占用内存&#xff0c;也容易导致栈溢出&#xff0c;于是只能尝试其它的方法。 下面采用的方式&#xff0c;只需要一次集合的遍历就可以实现树形的结构。 先手…

Spring 事务管理方案和事务管理器及事务控制的API

目录 一、事务管理方案 1. 修改业务层代码 2. 测试 二、事务管理器 1. 简介 2. 在配置文件中引入约束 3. 进行事务配置 三、事务控制的API 1. PlatformTransactionManager接口 2. TransactionDefinition接口 3. TransactionStatus接口 往期专栏&文章相关导读 …

Spring Boot 中的 @EnableConfigurationProperties 注解

Spring Boot 中的 EnableConfigurationProperties 注解 在 Spring Boot 中&#xff0c;EnableConfigurationProperties 注解是一个非常有用的注解&#xff0c;它可以用于启用对特定配置类的支持。在本文中&#xff0c;我们将深入探讨 EnableConfigurationProperties 注解&…

2023年最新整理网络安全护网蓝队面试题​

如何打击黑灰产工具 全面监控和快速响应&#xff08;溯源&#xff09;&#xff1a;对黑灰进行长期跟进&#xff0c;了解黑灰产工具的传播链条和路径&#xff0c;第一时间捕获活跃的黑灰产工具&#xff08;建立特征词监控&#xff0c;数据取样、交叉分析&#xff09; 建立软件指…

ReentrantReadWriteLock源码

介绍 用一个变量如何维护多种状态 在 ReentrantLock 中&#xff0c;使用 Sync ( 实际是 AQS )的 int 类型的 state 来表示同步状态&#xff0c;表示锁被一个线程重复获取的次数。 但是&#xff0c;读写锁 ReentrantReadWriteLock 内部维护着一对读写锁&#xff0c;如果要用一…

windows下VScode搭建IDApython脚本开发环境遇到的问题

开发环境 IDA pro 7.7 vscode 最新版 python版本 与IDA 自带python 一致 3.8.10 (小版本号也必须要一致) 安装插件 下载 插件仓库的地址&#xff1a;https://github.com/ioncodes/idacode release版本 将插件安装到 IDApath/plugins/ idacode ->setting.py 设置如下:…

SpringMVC原理分析 | Hello程序

&#x1f497;wei_shuo的个人主页 &#x1f4ab;wei_shuo的学习社区 &#x1f310;Hello World &#xff01; SpringMVC Spring MVC 是 Spring 提供的一个基于 MVC 设计模式的轻量级 Web 开发框架&#xff0c;本质上相当于 Servlet&#xff1b; 拥有结构最清晰的 ServletJSPJav…

一步一步学OAK之二: RGB相机控制

今天我们来实现 RGB相机的控制程序&#xff0c;用来控制彩色相机的曝光、灵敏度、白平衡、亮度/色度降噪、 设备端裁剪、相机触发器等。 目录 Setup 1: 创建文件Setup 2: 安装依赖Setup 3: 导入需要的包Setup 4: 全局变量Setup 5: 定义clamp函数Setup 6: 创建pipelineSetup 7:…

蜣螂优化算法(DBO)优化VMD参数,最小包络熵、样本熵、信息熵、排列熵(适应度函数可自行选择,一键修改)包含MATLAB源代码

蜣螂优化算法是华大学沈波教授团队&#xff0c;继麻雀搜索算法(Sparrow Search Algorithm&#xff0c;SSA&#xff09;之后&#xff0c;于2022年11月27日又提出的一种全新的群体智能优化算法。已有很多学者将算法用于实际工程问题中&#xff0c;今天咱们用蜣螂优化算法优化一下…

ASEMI代理光宝光耦LTV-6341的应用与性能分析

编辑-Z 本文将全面深入地探讨光耦LTV-6341的应用与性能。首先&#xff0c;我们将介绍光耦LTV-6341的基本概念和工作原理&#xff0c;然后&#xff0c;我们将详细分析其在电子设备中的应用&#xff0c;接着&#xff0c;我们将对其性能进行深入的分析&#xff0c;最后&#xff0…

python spider 爬虫 之 解析 xpath 、jsonpath、BeautifulSoup (二)

Jsonpath 安装&#xff1a; pip install -i https://pypi.tuna.tsinghua.edu.cn/simple jsonpath 使用&#xff1a;jsonpath 只能解析本地文件&#xff0c;跟xpath不一样 objjson.load(open(‘json文件’&#xff0c;‘r’, encoding‘utf-8’)) json.load(是文件&#xff0c;…