富文本编辑器图片上传并回显

1.概述

在代码业务需求中,我们会经常涉及到文件上传的功能,通常来说,我们存储文件是不能直接存储到数
据库中的,而是以文件路径存储到数据库中;但是存储文件的路径到数据库中又会有一定的问题,就是
浏览器是不能直接访问我们的本机的文件资源的;即便我们通过别的技术手段可以让浏览器访问本地资
源,那也是不安全的,基本上不会使用这样的手段;我们一般是把资源上传到服务器中。

2.使用步骤(纯前端上传版)

这里使用的富文本编辑器是 wangEditor ,且这里使用的是华为云的云存储技术 OBS ;本项目不打算做后
端连接,只是演示如何使用文件上传功能,想使用后端连接的小伙伴可以直接创建一个后端项目,只需
创建一个接口和一个接口参数便即可接收到前端的富文本编辑器的内容。

2.1 创建vue项目

vue 项目同学们基本上都会创建了,这里就不做过多的赘述

2.2创建一个页面,开始编辑页面

查看官方文档: 快速开始 | wangEditor
安装 npm install @wangeditor/editor --save npm install @wangeditor/editor
for-vue@next --save
复制粘贴 Demo 的代码即可完成富文本编辑器的编辑
在本项目中,我比较喜欢 vue3 的组合式语法,所以和官网的代码略有不同
<template>
<h2 style = "margin-left: 10vw" > 这是富文本编辑器 1 </h2>
<div class = "editView1" >
<div style = "height: 90%;border: 1px solid #ccc" >
<Toolbar
style = "border-bottom: 1px solid #ccc"
:editor = "editorRef"
:defaultConfig = "toolbarConfig"
:mode = "mode"
/>
<Editor
style = "height: 90%; overflow-y: hidden;"
v-model = "valueHtml"
:defaultConfig = "editorConfig"
:mode = "mode"
@onCreated = "handleCreated"
/>
</div>
<el-button> 点击提交 </el-button>
</div>
<h3 style = "margin-left: 10vw" > 这是提交到数据的文本内容 </h3>
<div style = "margin-top: 10px;width: 80vw;margin-left: 10vw;border: 1px solid" >
<p> {{valueHtml}} </p>
</div>
</template>
<script setup >
import '@wangeditor/editor/dist/css/style.css' ;
import { onBeforeUnmount , ref , shallowRef , onMounted } from 'vue' ;
import { Editor , Toolbar ,} from '@wangeditor/editor-for-vue' ;
// 编辑器实例,必须用 shallowRef
const editorRef = shallowRef ()
// 内容 HTML
const valueHtml = ref ( '<p>hello</p>' )
const toolbarConfig = {}
const editorConfig = {
placeholder : ' 请输入内容 ...' ,
}
// 组件销毁时,也及时销毁编辑器,也是一直进行触发
onBeforeUnmount (() => {
const editor = editorRef . value
if ( editor == null ) return
editor . destroy ()
})
const handleCreated = ( editor ) => {
editorRef . value = editor // 记录 editor 实例,重要!
}
</script>
<style scoped >
.editView1 {
width : 80vw ;
height : 50vh ;
margin-left : 10vw ;
}
</style>

2.3编辑图片上传功能

上面代码是没有文件上传的功能的,这个功能是需要我们自己添加的

先去官方文档找到菜单编辑部分: 菜单配置 | wangEditor
看到我圈的地方,将该代码添加到对应的地方
const editorConfig = {
placeholder: ' 请输入内容 ...',
MENU_CONF: {}
}

 在跳转到官方文档找到上传图片部分:菜单配置 | wangEditor

script代码块中,继续向后添加内容,里面就可以写上我们的上传图片的的相关代码

editorConfig.MENU_CONF['uploadImage'] = {
// 上传图片的配置
}
但不过我的项目中使用的是华为云存储技术,和同学们的可能有点出入,所以以下代码仅供参考,不能
直接复制粘贴使用
// 创建云存储的实例对象
var obsClient = new ObsClient({
access_key_id: " 填写 ak 密钥 ",
secret_access_key: " 填写 sk 密钥 ",
// 这里以我自己的访问路径为例,其他的话请按实际情况填写
server: 'https://obs.cn-north-4.myhuaweicloud.com'
});
// 自定义图片上传
editorConfig.MENU_CONF['uploadImage'] = {
async customUpload(file, insertFn) { // JS 语法
// file 即选中的文件 , 先上传对象文件
obsClient.putObject({
Bucket: 'beixuan',
Key: file.name,
SourceFile: file
}, function (err, result) {

if(err){

// 上传失败
console.error('Error-->' + err);
}else{
// 最后回显图片
// 自己实现上传,并得到图片 url alt href
var url = "https://beixuan.obs.cn-north-4.myhuaweicloud.com/"+file.name
var alt = file.name
var href = "https://beixuan.obs.cn-north-
4.myhuaweicloud.com/"+file.name
insertFn(url,alt,href)
}
});
}
}

 3.使用步骤(后端上传版)

3.1 界面创建还是上面的步骤只不过自定义上传的方法不同

// 自定义图片上传
editorConfig.MENU_CONF['uploadImage'] = {
// 自定义上传
async customUpload(file, insertFn) { // JS 语法
const formData = new FormData();
formData.append('image', file);
try {
const response = await axios.post('/UploadToWeb/upload/image', formData);
console.log(response)
if (response.errno == 0){
console.log(response.data)
insertFn(response.data.url, response.data.alt, response.data.href)
}
} catch (error) {
console.error('Error uploading file:', error);
}
// file 即选中的文件
// 自己实现上传,并得到图片 url alt href
// 最后插入图片
}

 3.2 创建后端程序(无数据库连接)

@RestController
@RequestMapping("/upload")
public class UploadController {
@RequestMapping("/image")
public ResultJSON uploadImage(@RequestParam("image") MultipartFile file){
//直接在代码中指定路径(不推荐,因为硬编码的路径不灵活)
String uploadDir = System.getProperty("catalina.base") + File.separator +
"webapps" + File.separator + "UploadToWeb" + File.separator + "image";
try {
// 确保上传目录存在
File uploadDirectory = new File(uploadDir);
if (!uploadDirectory.exists()) {
uploadDirectory.mkdirs();
}
// 构建目标文件路径
String fileName = file.getOriginalFilename();
// 这里你可以添加逻辑来避免文件名冲突或路径遍历攻击
File destFile = new File(uploadDirectory, fileName);
// 保存文件
file.transferTo(destFile);
ResData data = new ResData();
data.setUrl("http://192.168.78.132:8080/UploadToWeb/image/"+destFile.getName());
data.setAlt(fileName);
data.setUrl("http://192.168.78.132:8080/UploadToWeb/image/"+destFile.getName());
return ResultJSON.ok(data);
} catch (IOException e) {
e.printStackTrace();
return ResultJSON.err("系统错误,上传失败");
}
}
}

3.3 跨域解决

export default defineConfig({
plugins: [vue(),],
resolve: {
alias: {
'@': fileURLToPath(new URL('./src', import.meta.url))
}
},
//前端代理进行跨域决解问题
server:{
proxy:{
'/api':{ //将路径中含有api的路径就会进来到这里
changeOrigin:true, //是否切换源
target:"http://192.168.78.132:8080/", //确定切换源后需要切换成哪一
个源
rewrite:(path) => path.replace(/^\/api/,'') //是否重写路径,重写成什么路径
//上面表示说重写路径时,由于后端的接口中除了没有/api这个部分外,其他的的一样,所以
把'/api'替换成空字符串就是一样的了
}
}

 3.4 打包成war包及部署到tomcat服务器上

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

黑马程序员Java笔记整理(day05)

1.面向对象编程 2.用法 3.对象是什么 4.对象在计算机中是啥 5.无参与有参构造器 小结: 6.this的作用 7.小结 8.封装 9.小结 10.实体类 11.小结 12.static 13.小结 14.static修饰方法 15.static应用前景 16.几个注意事项 17.java中可以直接用类的名字创建数组&#xff0c;如: M…

微服务即时通讯系统的实现(服务端)----(2)

目录 1. 语音识别子服务的实现1.1 功能设计1.2 模块划分1.3 模块功能示意图1.4 接口的实现 2. 文件存储子服务的实现2.1 功能设计2.2 模块划分2.3 模块功能示意图2.4 接口的实现 3. 用户管理子服务的实现3.1 功能设计3.2 模块划分3.3 功能模块示意图3.4 数据管理3.4.1 关系数据…

Windows系统怎么把日历添加在桌面上用来记事?

在众多电脑操作系统中&#xff0c;Windows系统以其广泛的用户基础和强大的功能&#xff0c;成为许多人的首选。对于习惯于在电脑前工作和学习的用户来说&#xff0c;能够直接在桌面上查看和记录日历事项&#xff0c;无疑会大大提高工作效率和生活便利性。今天&#xff0c;就为大…

org.apache.commons.lang3包下的StringUtils工具类的使用

前言 相信平时在写项目的时候&#xff0c;一定使用到StringUtils.isEmpty()&#xff1b;StringUtils.isBlank();但是你真的了解他们吗&#xff1f; 也许你两个都不知道&#xff0c;也许你除了isEmpty/isNotEmpty/isNotBlank/isBlank外&#xff0c;并不知道还有isAnyEmpty/isNon…

【ROS2】ROS2 Hello World (C++实现)

ROS 系列学习教程(总目录) ROS2 系列学习教程(总目录) 目录 一、Hello World工程简介二、ROS2 Hello World C版2.1 创建工作空间目录2.2 创建功能包2.3 编辑源文件2.4 编辑编译配置文件CMakeList.txt2.5 编译工程2.6 运行节点 万物始于Hello World&#xff0c;为了体验ROS2&…

springboot 整合 rabbitMQ (延迟队列)

前言&#xff1a; 延迟队列是一个内部有序的数据结构&#xff0c;其主要功能体现在其延时特性上。这种队列存储的元素都设定了特定的处理时间&#xff0c;意味着它们需要在规定的时间点或者延迟之后才能被取出并进行相应的处理。简而言之&#xff0c;延时队列被设计用于存放那…

电路基础——相量法

相量法 为什么要使用相量表示&#xff1f; 电路方程是微分方程&#xff1a; 电路的运算&#xff08;如KCL、KVL方程运算&#xff09;会涉及到两个正弦量的相加&#xff1a; 如下图所示同频率的正弦量相加仍得到同频率的正弦量&#xff0c;因此只需确定初相位和有效值。 基于上…

深度学习:梯度下降法

损失函数 L&#xff1a;衡量单一训练样例的效果。 成本函数 J&#xff1a;用于衡量 w 和 b 的效果。 如何使用梯度下降法来训练或学习训练集上的参数w和b &#xff1f; 成本函数J是参数w和b的函数&#xff0c;它被定义为平均值&#xff1b; 损失函数L可以衡量你的算法效果&a…

ProtonBase 教育行业解决方案

01/方案概述 当前&#xff0c;大数据、云计算等技术正加速教育行业的数字化转型&#xff0c;教学模式从线下转向线上&#xff0c;传统教育企业向具有互联网性质的新型教育企业转变。在此背景下&#xff0c;教育企业亟需探索多源数据的融合扩展&#xff0c;以应对复杂的业务场景…

Socket编程(TCP/UDP详解)

前言&#xff1a;之前因为做项目和找实习没得空&#xff0c;计算机网络模块并没有写成博客&#xff0c;最近得闲了&#xff0c;把计算机网络模块博客补上。 目录 一&#xff0c;UDP编程 1&#xff09;创建套接字 2&#xff09;绑定端口号 3&#xff09;发送与接收数据 4&…

求平均年龄

求平均年龄 C语言代码C 代码Java代码Python代码 &#x1f490;The Begin&#x1f490;点点关注&#xff0c;收藏不迷路&#x1f490; 班上有学生若干名&#xff0c;给出每名学生的年龄&#xff08;整数&#xff09;&#xff0c;求班上所有学生的平均年龄&#xff0c;保留到小数…

40分钟学 Go 语言高并发:GC原理与优化

GC原理与优化 一、GC基础知识概览 方面核心概念重要性优化目标GC算法三色标记法、并发GC⭐⭐⭐⭐⭐理解GC工作原理垃圾回收策略触发条件、回收步骤⭐⭐⭐⭐⭐掌握GC过程GC调优参数设置、性能监控⭐⭐⭐⭐优化GC效果内存管理内存分配、内存逃逸⭐⭐⭐⭐⭐减少内存压力 让我们…

论文笔记 SliceGPT: Compress Large Language Models By Deleting Rows And Columns

欲买桂花同载酒&#xff0c;终不似&#xff0c;少年游。 数学知识 秩&#xff1a; 矩阵中最大线性无关的行/列向量数。行秩与列秩相等。 线性无关&#xff1a;对于N个向量而言&#xff0c;如果任取一个向量 v \textbf{v} v&#xff0c;不能被剩下的N-1个向量通过线性组合的方式…

vscode的项目给gitlab上传

目录 一.创建gitlab帐号 二.在gitlab创建项目仓库 三.Windows电脑安装Git 四.vscode项目git上传 一.创建gitlab帐号 二.在gitlab创建项目仓库 图来自:Git-Gitlab中如何创建项目、创建Repository、以及如何删除项目_gitlab新建项目-CSDN博客&#xff09; 三.Windows电脑安…

电阻可靠性的内容

一、影响电阻可靠性的因素&#xff1a; 影响电阻可靠性的因素有温度系数、额定功率&#xff0c;最大工作电压、固有噪声和电压系数 &#xff08;一&#xff09;温度系数 电阻的温度系数表示当温度改变1摄氏度时&#xff0c;电阻阻值的相对变化&#xff0c;单位为ppm/℃.电阻温…

(计算机网络)期末

计算机网络概述 物理层 信源就是发送方 信宿就是接收方 串行通信--一次只发一个单位的数据&#xff08;串行输入&#xff09; 并行通信--一次可以传输多个单位的数据 光纤--利用光的反射进行传输 传输之前&#xff0c;要对信源进行一个编码&#xff0c;收到信息之后要进行一个…

【K230 CanMV】machine.FPIOA、Pin 与 GPIO 全解析

引言&#xff1a;在嵌入式开发领域&#xff0c;GPIO&#xff08;通用输入输出&#xff09;引脚的功能配置和复用能力对设备的灵活性和功能实现起到了至关重要的作用。FPIOA&#xff08;Field Programmable IO Array&#xff0c;现场可编程 IO 数组&#xff09;是现代嵌入式芯片…

Observability:如何在 Kubernetes pod 中轻松添加应用程序监控

作者&#xff1a;来自 Elastic Jack Shirazi•Sylvain Juge•Alexander Wert Elastic APM K8s Attacher 允许将 Elastic APM 应用程序代理&#xff08;例如 Elastic APM Java 代理&#xff09;自动安装到 Kubernetes 集群中运行的应用程序中。该机制使用变异 webhook&#xff0…

【QT入门到晋级】QT项目打生产环境包--(Linux和window)

前言 使用QTcreator完成正常编译后&#xff0c;在构建目录中有可执行程序生成&#xff0c;如果直接把可执行程序拷贝到干净的生产环境上是无法运行成功的&#xff0c;使用ldd&#xff08;查看程序依赖包&#xff09;会发现缺失很多QT的特性包&#xff0c;以及将介绍国产Linux桌…

Flutter:页面滚动

1、单一页面&#xff0c;没有列表没分页的&#xff0c;推荐使用&#xff1a;SingleChildScrollView() return Scaffold(backgroundColor: Color(0xffF6F6F6),body: SingleChildScrollView(child: _buildView()) );2、列表没分页&#xff0c;如购物车页&#xff0c;每个item之间…