uniapp h5端临时路径转file对象上传

文章目录

  • 问题说明
  • 使用说明
    • 1.使用场景
    • 2. 文件需要压缩
    • 3. 使用技术
    • 4. 代码如下
    • 5. utils/index.js 代码
  • 3. 总结说明

问题说明

  1. 只针对uniapp开发H5网页,使用uniapp api获取到的临时路径不能满足使用场景,其他平台未进行测试

使用说明

1.使用场景

使用uview-ui的u-upload组件上传图片

2. 文件需要压缩

我的业务场景是上传图片之后,需要使用ocr识别,文件太大的话,识别比较缓慢,所以需要进行压缩

3. 使用技术

// npm install compressorjs
import Compressor from 'compressorjs';

4. 代码如下

这是在u-upload组件的基础上进行封装的ImageUpload组件, 先获取到临时路径,通过fetch请求获取到blob对象,然后再进行转file处理,相应的处理函数是tempFilePathToFile,compressFile

<template><view class="upload-container"><u-upload :previewImage="true" :max-count="maxCount" :auto-upload="false" @afterRead="handleAfterRead"@beforeRead="handleBeforeRead" :useBeforeRead="true" @delete="handleDelete" :multiple="multiple":accept="accept" :fileList="fileList"><slot name="file"></slot></u-upload></view>
</template><script>
import { getToken, tempFilePathToFile, compressFile } from "@/utils";
import { uploadFile } from "@/utils/api";export default {data() {return {fileList: [// {//     url: "/dev-api/profile/upload/2024/10/30/公司logo_20241030231031A009.jpg",// },],};},props: {value: [String, Object, Array],maxCount: {type: Number,default: 1,},// 文件大小限制 MfileSize: {type: Number,default: 20,},fileType: {type: Array,default: () => ["jpg", "png", "jpeg"],},accept: {type: String,default: "image",},multiple: {type: Boolean,default: false,},//  是否压缩的阈值 单位Mthreshold: {type: Number,default: 1,},},watch: {value: {handler(val) {if (val) {// 首先将值转为数组const list = Array.isArray(val)? val: this.value.split(",");// 然后将数组转为对象数组this.fileList = list.map((item) => {if (typeof item === "string") {let baseURL = this.globalVar.request.baseURL;if (item.indexOf(baseURL) === -1) {item = {name: baseURL + item,url: baseURL + item,};} else {item = { name: item, url: item };}}return item;});} else {this.fileList = [];return [];}},deep: true,immediate: true,},},methods: {// uploadFilePromise(url) {//     return new Promise((resolve, reject) => {//         uni.uploadFile({//             url: `${this.globalVar.request.baseURL}/common/upload`, // 仅为示例,非真实的接口地址//             filePath: url,//             name: "file",//             header: {//                 Authorization: "Bearer " + getToken(),//             },//             success: (res) => {//                 setTimeout(() => {//                     resolve(JSON.parse(res.data));//                 }, 1000);//             },//         });//     });// },uploadFilePromise(file) {return new Promise(async (resolve, reject) => {try {let formData = new FormData();formData.append("file", file, file.name);fetch(`${this.globalVar.request.baseURL}/common/upload`, {method: "POST",headers: {Authorization: "Bearer " + getToken(),},body: formData,}).then((res) => res.json()).then((res) => {resolve(res);});} catch (error) {console.log(error);resolve(null);}});},handleBeforeRead(e) {let files = typeof e.file === "object" ? [e.file] : e.file;let isLimitSize = files.some((file) => file.size > this.fileSize * 1024 * 1024);if (isLimitSize) {this.$u.toast(`文件大小不能超过${this.fileSize}MB`);return false;}let isLimitType = files.some((file) => !this.fileType.includes(file.name.split(".").pop()));if (isLimitType) {this.$u.toast(`仅支持${this.fileType.join(",")}格式`);return false;}return true;},async handleAfterRead(e) {let files = typeof e.file === "object" ? [e.file] : e.file;files.map((item) => {this.fileList.push({...item,status: "uploading",message: "上传中",});});let start = 0;for (let i = 0; i < files.length; i++) {let item = files[i];let file = await tempFilePathToFile({tempFilePath: item.url,fileName: item.name,});// 判断是否需要压缩if (file.size > this.threshold * 1024 * 1024) {file = await compressFile(file, { quality: 0.2 });}let res = await this.uploadFilePromise(file);if (res.code == 200) {this.fileList.splice(start,1,Object.assign(item, {status: "success",message: "",url: this.globalVar.request.baseURL + res.fileName,}));} else {this.fileList.splice(start,1,Object.assign(item, {status: "error",message: "上传失败",}));}start++;}this.$emit("input", this.listToString(this.fileList));let list = this.fileList.map((item) => {item.url = item.url.replace(this.globalVar.request.baseURL, "");return item;});this.$emit("change", list);},handleDelete(e) {this[`fileList`].splice(e.index, 1);this.$emit("input", this.listToString(this.fileList));// this.$emit("change", this.fileList);},// 对象转成指定字符串分隔listToString(list, separator) {let strs = "";separator = separator || ",";for (let i in list) {if (list[i].url) {strs +=list[i].url.replace(this.globalVar.request.baseURL,"") + separator;}}return strs != "" ? strs.substr(0, strs.length - 1) : "";},},
};
</script><style scoped>
.upload-container {padding: 20px;
}.upload-btn {display: flex;align-items: center;justify-content: center;border: 1px dashed #d9d9d9;border-radius: 5px;padding: 20px;cursor: pointer;
}.upload-file {position: relative;margin-top: 10px;
}.upload-file image {border: 1px solid #d9d9d9;border-radius: 5px;
}.upload-file .u-icon {position: absolute;top: 5px;right: 5px;
}
</style>

5. utils/index.js 代码

import Compressor from 'compressorjs';export const getToken = () => uni.getStorageSync('token') || '';export const removeToken = () => uni.removeStorageSync('token');export const base64Encode = (str) => {// 将字符串转换为 UTF-8 编码的字节数组const utf8Bytes = new TextEncoder().encode(str);// 将字节数组转换为 Base64 字符串return btoa(String.fromCharCode.apply(null, utf8Bytes));
};export const base64Decode = (base64) => {// 将 Base64 字符串转换为字节数组const byteString = atob(base64);// 将字节数组转换为 UTF-8 字符串const bytes = new Uint8Array(byteString.length);for (let i = 0; i < byteString.length; i++) {bytes[i] = byteString.charCodeAt(i);}return new TextDecoder().decode(bytes);
};export const goPageByPath = (path, query = {}) => {if (!path) {throw new Error('缺少必须的path参数');}let queryLen = Object.keys(query).length;let queryStr = '';if (queryLen) {queryStr = Object.keys(query).map((key) => `${key}=${query[key]}`).join('&');queryStr = `?${queryStr}`;}uni.navigateTo({url: `${path}${queryStr}`});
};// 表单重置
export function resetForm(refName) {if (this.$refs[refName]) {this.$refs[refName].resetFields();}
}// 判断 是否是数字
export const isStrictNumber = (value) => {return typeof value === 'number' && !isNaN(value);
};// 获取文件的后缀名,不包含 .
export const getFileExt = (fileName) => {return fileName.split('.').pop();
};// 临时路径转file对象 针对h5端
export const tempFilePathToFile = ({tempFilePath, fileName}) => {if (!tempFilePath) {return Promise.resolve(null);}return new Promise(async (resolve, reject) => {try {const response = await fetch(tempFilePath);const blob = await response.blob();const mimeType = response.headers.get('content-type');const file = new File([blob], fileName, {type: mimeType});resolve(file);} catch (error) {resolve(null);}});
};// 压缩文件
export const compressFile = (file, options) => {return new Promise((resolve, reject) => {new Compressor(file, {...options,success(result) {resolve(result);},error(err) {reject(err);},});});
};

3. 总结说明

可能有更好的处理方式, 如果大家有更好的处理方式,可以在评论区,贴出代码,让播主也学习一下,学无止境

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

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

相关文章

微服务网关的认证管理;原理与实践

API安全认证是网关的最重要能力 API 网关为了保护对外提供的API&#xff0c;避免诸如恶意访问、未授权访问、应用漏洞及黑客攻击等导致的数据和资产损失&#xff0c;采用API网关的认证机制显得十分必要。 这种认证机制通过基于token的身份验证来实现&#xff0c;它允许应用程…

STM32 + CubeMX + 硬件SPI + W5500 +TcpClient

这篇文章记录一下STM32W5500TCP_Client的调试过程&#xff0c;实现TCP客户端数据的接收与发送。 目录 一、W5500模块介绍二、Stm32CubeMx配置三、Keil代码编写1、添加W5500驱动代码到工程&#xff08;添加方法不赘述&#xff0c;驱动代码可以在官网找&#xff09;2、在工程中增…

微信小程序中,点击视频,没有跳转播放,可能是因为没有在app.json中正确注册视频播放页面的路径

const customMethodMap {handlePreview(e) {const { item: { url } } e?.currentTarget?.datasetconsole.log(Clicked item URL:, url); // 输出URLconst type url.split(.)[url.split(.)?.length - 1]console.log(File type:, type); // 输出文件类型console.log(isDoc(…

软件体系结构

第一章 构件 具有某种功能的 可复用的软件结构单元,为组装服务,可部署,具有规范的接口规约和显式的语境依赖 构件模型 构件模型是对构件本质特征的抽象描述&#xff0c;可以把它想象成一个类的组合&#xff0c;它封装了多个类&#xff0c;并具有一个或多个服务而提供了简单…

Spark 的Standalone集群环境安装与测试

目录 一、Standalone 集群环境安装 &#xff08;一&#xff09;理解 Standalone 集群架构 &#xff08;二&#xff09;Standalone 集群部署 二、打开监控界面 &#xff08;一&#xff09;master监控界面 &#xff08;二&#xff09;日志服务监控界面 三、集群的测试 &a…

react的antd-mobile使用Steps显示物流

antd-mobile的图标&#xff0c;是需要安装依赖的 step如果只有一个步骤是不会展示的&#xff0c;代码里面的标题那块可以看出来 尝试了很多遍测试发现一直不显示&#xff0c;查询后发现是这个组件的本身设置的原因 那么就算你只展示一个那么也要写两个step&#xff0c;第二个…

基于鸟类AI识别的果园智能物联网解决方案

1. 项目背景 我国拥有广阔的果园种植面积&#xff0c;但每年因鸟类造成的损失高达数亿元。传统的防鸟害措施&#xff0c;如建立防护网和使用物理化学方法&#xff0c;效果并不理想&#xff0c;且成本较高。为了解决这一问题&#xff0c;深圳快瞳科技有限公司的提出基于鸟类AI识…

让Erupt框架支持.vue文件做自定义页面模版

Erupt是什么&#xff1f; Erupt 是一个低代码 全栈类 框架&#xff0c;它使用 Java 注解 动态生成页面以及增、删、改、查、权限控制等后台功能。 零前端代码、零 CURD、自动建表&#xff0c;仅需 一个类文件 简洁的注解配置&#xff0c;快速开发企业级 Admin 管理后台。 提…

如何优雅处理异常?处理异常的原则

前言 在我们日常工作中&#xff0c;经常会遇到一些异常&#xff0c;比如&#xff1a;NullPointerException、NumberFormatException、ClassCastException等等。 那么问题来了&#xff0c;我们该如何处理异常&#xff0c;让代码变得更优雅呢&#xff1f; 1 不要忽略异常 不知…

DBAPI连接阿里云 maxcompute 报错

使用正确的驱动包 访问以下链接寻找驱动包 https://github.com/aliyun/aliyun-odps-jdbc/releases/tag/v3.4.3 注意要使用odps-jdbc-3.4.3-jar-with-dependencies.jar &#xff0c;这个是完整的jar包 不要使用odps-jdbc-3.4.3.jar&#xff0c;这个不是完整的&#xff0c;它还…

2024最新Python安装教程+Pycharm安装教程【附安装包】

Python安装 1.首先下载好Python安装包 获取方式&#xff1a;点击这里&#xff08;扫描神秘②薇码免下载&#xff09;完全免费&#xff01;&#xff01;&#xff01; 2.打开安装包&#xff0c;先勾选最下面两个选项&#xff0c;再选择第二个自定义安装 3.这里默认全选&#xff…

【数据库】elasticsearch

1、架构 es会为每个索引创建一定数量的主分片和副本分片。 分片&#xff08;Shard&#xff09;&#xff1a; 将索引数据分割成多个部分&#xff0c;每个部分都是一个独立的索引。 主要目的是实现数据的分布式存储和并行处理&#xff0c;从而提高系统的扩展性和性能。 在创建索…

JAVA基础:数组 (习题笔记)

一&#xff0c;编码题 1&#xff0c;数组查找操作&#xff1a;定义一个长度为10 的一维字符串数组&#xff0c;在每一个元素存放一个单词&#xff1b;然后运行时从命令行输入一个单词&#xff0c;程序判断数组是否包含有这个单词&#xff0c;包含这个单词就打印出“Yes”&…

【学习】使用webpack搭建react项目

前言 在日常工作中&#xff0c;我大多是在已有的项目基础上进行开发&#xff0c;而非从头构建项目。因此&#xff0c;我期望通过本次学习能填补我在项目初始化阶段知识的空白&#xff0c;与大家共同进步。在此过程中&#xff0c;我欢迎并感激任何指正或建议&#xff0c;无论是…

什么是人工智能体?

人工智能体&#xff08;AI Agent&#xff09;是指能够感知环境、做出决策并采取行动以实现特定目标的自主实体。以下是对人工智能体的具体介绍&#xff1a; 定义与核心概念 智能体的定义&#xff1a;智能体&#xff0c;英文名为Agent&#xff0c;是指具有智能的实体&#xff0…

【初阶数据结构篇】链式结构二叉树(续)

文章目录 须知 &#x1f4ac; 欢迎讨论&#xff1a;如果你在学习过程中有任何问题或想法&#xff0c;欢迎在评论区留言&#xff0c;我们一起交流学习。你的支持是我继续创作的动力&#xff01; &#x1f44d; 点赞、收藏与分享&#xff1a;觉得这篇文章对你有帮助吗&#xff1…

二叉树 最大深度(递归)

给定一个二叉树 root &#xff0c;返回其最大深度。 二叉树的 最大深度 是指从根节点到最远叶子节点的最长路径上的节点数。 示例 1&#xff1a; 输入&#xff1a;root [3,9,20,null,null,15,7] 输出&#xff1a;3示例 2&#xff1a; 输入&#xff1a;root [1,null,2] 输出…

python机器人Agent编程——实现一个本地大模型和爬虫结合的手机号归属地天气查询Agent

目录 一、前言二、准备工作三、Agent结构四、python模块实现4.1 实现手机号归属地查询工具4.2实现天气查询工具4.3定义创建Agent主体4.4创建聊天界面 五、小结PS.扩展阅读ps1.六自由度机器人相关文章资源ps2.四轴机器相关文章资源ps3.移动小车相关文章资源ps3.wifi小车控制相关…

python安装selenium,geckodriver,chromedriver

安装浏览器 找到浏览器的版本号 chrome 版本 130.0.6723.92&#xff08;正式版本&#xff09; &#xff08;64 位&#xff09; firfox 116.0.3 (64 位)&#xff0c;但是后面运行的时候又自动更新到了 127.0.0.8923 安装selenium > pip install selenium > pip show …

基于SSM+uniapp的营养食谱系统+LW参考示例

1.项目介绍 功能模块&#xff1a;用户管理、年龄类型管理、阶段食谱管理、体质类型管理、季节食谱管理、职业食谱管理等系统角色&#xff1a;管理员、普通用户技术栈&#xff1a;SSM&#xff0c;uniapp&#xff0c; Vue等测试环境&#xff1a;idea2024&#xff0c;HbuilderX&a…