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;它允许应用程…

C++学习笔记2----模板类、继承、struct在class内定义相关问题记录

背景&#xff1a;写的算法合并到项目组代码&#xff0c;编译发现一些以前没积累过的错误&#xff0c;这里记录下&#xff0c;也供大家参考。 一、问题1 // 每个类都有单独的.h .cpp class A; class B : public A {// ... }; class C : public A {// ... };若在B.h中引用了一个…

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;并具有一个或多个服务而提供了简单…

什么是垃圾回收(Garbage Collection)?

垃圾回收&#xff08;Garbage Collection&#xff09;是一种自动管理内存的机制&#xff0c;在编程语言中&#xff0c;它负责自动检测和释放不再被程序使用的内存&#xff0c;以避免内存泄漏和内存碎片的问题。 以下是一段示例代码&#xff1a; public class Example {public…

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识…

uniapp 使用vue/pwa

vue add vue/pwa src下创建service-worker.js /* eslint-disable no-undef*/ importScripts(https://storage.googleapis.com/workbox-cdn/releases/5.1.2/workbox-sw.js) if (workbox) {console.log(Yay! Workbox is loaded &#x1f389;) } else {console.log(Boo! Workbo…

Java 实现接口幂等的九种方法:确保系统稳定性与数据一致性

摘要&#xff1a; 在分布式系统中&#xff0c;接口的幂等性至关重要&#xff0c;它能确保重复请求不会导致意外的副作用。本文深入探讨了 Java 实现接口幂等的九种方法&#xff0c;包括数据库唯一约束、状态机、分布式锁等&#xff0c;并通过详细的代码示例和实际应用场景&…

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

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

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

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

OCR与PaddleOCR介绍

OCR技术与PaddleOCR的介绍 在数字化时代&#xff0c;光学字符识别&#xff08;OCR&#xff0c;Optical Character Recognition&#xff09;技术变得越来越重要。OCR技术可以将图像中的文本转换为可编辑和可搜索的文本格式&#xff0c;广泛应用于文档数字化、自动化数据输入、车…

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…

Fatal error: Uncaught Error: Call to undefined function mysql_connect() 解决办法详细

情况一 Fatal error: Uncaught Error: Call to undefined function mysql_connect() in /www/wwwroot/www.ygwzjs.cn/dg_upload/class/db_sql.php:72 Stack trace: #0 /www/wwwroot/www.ygwzjs.cn/dg_upload/class/combakfun.php(192): do_dbconnect_common(localhost, , guiz…

【数据库】elasticsearch

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

Oracle 第19章:高级查询技术

在Oracle数据库中&#xff0c;高级查询技术是数据库管理员和开发人员必须掌握的重要技能。这些技术能够帮助优化查询性能&#xff0c;简化复杂的查询逻辑&#xff0c;并提高数据处理的效率。本章将重点讨论两个关键概念&#xff1a;子查询和连接与并集操作。 子查询 定义: 子…

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

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