Vue项目快速整合WangEditor富文本编辑器

Vue项目快速整合WangEditor富文本编辑器

在这里插入图片描述
在这里插入图片描述

一、安装依赖

npm i wangeditor --save   //富文本编辑器
npm install highlight.js -S    //代码高亮
npm install dompurify  vue-dompurify-html  // 防xss 库

二、app.vue代码案例

已对接图片、视频接口 ,具体看如下代码案例 。

2.1、图片接口数据格式
{
  "data": [
    {
      "alt": "图片文字说明",
      "href": "跳转链接",
      "url": "http://localhost:8080/uploads/1727435190_2.jpg"
    }
  ],
  "errno": 0
}
2.2、视频接口数据格式
{
  "data": {
    "url": "http://localhost:8080/uploads/1727435236_20240920_092347.mp4"
  },
  "errno": 0
}
<template>
  <div id="app">
    <h1>Hello WangEditor</h1>
    <button @click="logEditorContent">输出编辑器内容</button>
    <br>
    <br>
    <div ref="editorContainer" style="height: 300px; border: 1px solid #ccc;"></div>
  </div>
</template>

<script>
import E from 'wangeditor';
import 'highlight.js/styles/github.css';

export default {
  name: 'App',
  data() {
    return {
      editor: null,
    };
  },
  mounted() {
    this.$nextTick(() => {
      this.editor = new E(this.$refs.editorContainer);

      // 配置图片上传的服务器接口
      this.editor.config.uploadImgServer = 'http://localhost:8080/upload';
      this.editor.config.uploadFileName = 'file';

      // 配置视频上传的服务器接口
      this.editor.config.uploadVideoServer = 'http://localhost:8080/upload-video';
      this.editor.config.uploadVideoName = 'file';

      this.editor.highlight = window.hljs;

      // 图片上传的回调处理逻辑
      this.editor.config.uploadImgHooks = {
        customInsert: (insertImgFn, result) => {
          if (result.errno === 0 && result.data && Array.isArray(result.data) && result.data.length > 0) {
            const imageData = result.data[0];
            if (imageData.url && typeof imageData.url === 'string' && imageData.url.trim() !== '') {
              insertImgFn(imageData.url, imageData.alt, imageData.href);
            }
          }
        },
      };

      // 视频上传的回调处理逻辑
      this.editor.config.uploadVideoHooks = {
        customInsert: (insertVideoFn, result) => {
          if (result.errno === 0 && result.data && result.data.url) {
            insertVideoFn(result.data.url);
          } else {
            console.error('视频上传失败');
          }
        },
      };

      this.editor.create();
    });
  },
  beforeDestroy() {
    if (this.editor) {
      this.editor.destroy();
    }
  },
  methods: {
    logEditorContent() {
      if (this.editor) {
        const content = this.editor.txt.html();  // 获取编辑器中的HTML内容
        console.log("编辑器内容:", content);
      }
    },
  },
};
</script>

<style>
#app {
  width: 80%;
  margin: 20px auto;
}

.w-e-text-container {
  min-height: 300px;
}
</style>

go后端接口案例,可直接复制用

package main

import (
	"fmt"
	"github.com/gin-gonic/gin"
	"mime/multipart"
	"net/http"
	"path/filepath"
	"strings"
	"time"
)

func main() {
	router := gin.Default()

	// 跨域中间件
	router.Use(CORSMiddleware())

	// 静态文件服务,将 "./uploads" 目录公开
	router.Static("/uploads", "./uploads")

	// 图片上传接口
	router.POST("/upload", uploadFile)

	// 视频上传接口
	router.POST("/upload-video", uploadVideo)

	// 启动服务器,监听8080端口
	router.Run(":8080")
}

// 上传文件处理(图片)
func uploadFile(c *gin.Context) {
	uploadCommon(c, "image")
}

// 上传视频处理
func uploadVideo(c *gin.Context) {
	uploadCommon(c, "video")
}

// uploadCommon 是通用的文件上传处理函数,接受图片或视频
func uploadCommon(c *gin.Context, fileTypeExpected string) {
	file, err := c.FormFile("file")
	if err != nil {
		c.JSON(http.StatusBadRequest, gin.H{
			"errno": 1,
			"data":  gin.H{},
		})
		return
	}

	// 使用时间戳生成唯一文件名
	filename := fmt.Sprintf("%d_%s", time.Now().Unix(), filepath.Base(file.Filename))
	savePath := filepath.Join("./uploads", filename)

	// 保存文件到指定路径
	if err := c.SaveUploadedFile(file, savePath); err != nil {
		c.JSON(http.StatusInternalServerError, gin.H{
			"errno": 1,
			"data":  gin.H{},
		})
		return
	}

	// 判断文件类型
	fileType := getFileType(file)

	if fileType == fileTypeExpected {
		// 如果文件类型匹配(图片或视频),根据不同类型返回相应的 JSON 响应
		if fileType == "image" {
			c.JSON(http.StatusOK, gin.H{
				"errno": 0,
				"data": []gin.H{
					{
						"url":  "http://localhost:8080/uploads/" + filename,
						"alt":  "图片文字说明",
						"href": "跳转链接",
					},
				},
			})
		} else if fileType == "video" {
			c.JSON(http.StatusOK, gin.H{
				"errno": 0,
				"data": gin.H{
					"url": "http://localhost:8080/uploads/" + filename,
				},
			})
		}
	} else {
		// 文件类型不匹配
		c.JSON(http.StatusBadRequest, gin.H{
			"errno": 1,
			"data":  gin.H{},
		})
	}
}

// getFileType 返回文件的 MIME 类型
func getFileType(file *multipart.FileHeader) string {
	ext := strings.ToLower(filepath.Ext(file.Filename))
	switch ext {
	case ".jpg", ".jpeg", ".png", ".gif", ".bmp":
		return "image"
	case ".mp4", ".avi", ".mkv", ".mov":
		return "video"
	default:
		return "other"
	}
}

// CORSMiddleware 处理跨域请求的中间件
func CORSMiddleware() gin.HandlerFunc {
	return func(c *gin.Context) {
		c.Writer.Header().Set("Access-Control-Allow-Origin", "*")
		c.Writer.Header().Set("Access-Control-Allow-Methods", "POST, GET, OPTIONS, PUT, DELETE")
		c.Writer.Header().Set("Access-Control-Allow-Headers", "Origin, Content-Type, X-Auth-Token, Authorization")

		// 处理预检请求
		if c.Request.Method == "OPTIONS" {
			c.AbortWithStatus(http.StatusNoContent)
			return
		}

		c.Next()
	}
}

三、预防xss代码案例

首先main.js文件装载
在这里插入图片描述

import DOMPurify from 'dompurify';

Vue.directive('dompurify-html', {
  bind(el, binding) {
    // 使用 DOMPurify 清理绑定的 HTML 内容
    el.innerHTML = DOMPurify.sanitize(binding.value);
  },
  update(el, binding) {
    // 每次数据更新时再次清理内容
    el.innerHTML = DOMPurify.sanitize(binding.value);
  }
});
<template>
  <div id="app">
    <h1>安全渲染 HTML 内容</h1>
    <div v-dompurify-html="htmlContent"></div>
  </div>
</template>

<script>
export default {
  data() {
    return {
      // 动态 HTML 内容,可能来自用户输入或外部数据
      htmlContent: '<p οnclick="alert(\'XSS\')">这是一些<strong>带有恶意代码</strong>的HTML</p>'
    };
  }
};
</script>

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

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

相关文章

基于飞腾平台的OpenCV的编译与安装

【写在前面】 飞腾开发者平台是基于飞腾自身强大的技术基础和开放能力&#xff0c;聚合行业内优秀资源而打造的。该平台覆盖了操作系统、算法、数据库、安全、平台工具、虚拟化、存储、网络、固件等多个前沿技术领域&#xff0c;包含了应用使能套件、软件仓库、软件支持、软件适…

景联文科技精准数据标注:优化智能标注平台,打造智能未来

景联文科技是一家致力于为人工智能提供全面数据标注解决方案的专业公司。 拥有一支由经验丰富的数据标注师和垂直领域专家组成的团队&#xff0c;确保数据标注的质量和专业性。 自建平台功能一站式服务平台&#xff0c;提供从数据上传、标注、审核到导出的一站式服务&#xff0…

Linux安装tomcat及配置环境变量超详细教程

微服务Linux解析部署使用全流程 linux系统的常用命令 Linux安装vim超详细教程 Linux安装JDK及配置环境变量超详细教程 1、上传压缩包 统一创建目录&#xff1a;/usr/local/tomcat&#xff0c;将压缩包上传到这个目录下。拖动文件到这个目录下即可。 2、执行解压命令 先进…

Sentinel-1 数据处理时如何手动下载高程数据

在Sentinel-1 数据数据预处理时&#xff0c;会使用高程数据进行地形校正。但选择自动下载高程时&#xff0c;由于网络原因经常会卡死&#xff0c;造成预处理过程不能正常进行&#xff01; 这个问题经过我的反复实践&#xff0c;可以通过手动下载高程数据来解决。下面是具体方法…

章管家 listUploadIntelligent.htm SQL注入漏洞

漏洞描述&#xff1a; 章管家 listUploadIntelligent.htm 接口处存在SQL注入漏洞&#xff0c;未经身份验证的远程攻击者除了可以利用 SQL 注入漏洞获取数据库中的信息&#xff08;例如&#xff0c;管理员后台密码、站点的用户个人信息&#xff09;之外&#xff0c;甚至在高权限…

软件功能测试需进行哪些测试?第三方软件测评机构有哪些测试方法?

在信息化社会迅速发展的今天&#xff0c;软件功能测试在软件开发生命周期中占据着不可或缺的地位。软件功能测试是评估软件系统是否符合预期功能和用户需求的过程。其重要性体现在提升软件质量、确保用户满意度以及降低维护成本等方面。 软件功能测试是对软件应用程序进行的一…

robomimic应用教程(二)——策略运行与评估

得到训练好的pth后&#xff0c;下一并将其进行部署及效果评估 可以在jupyter notebook中进行此操作&#xff0c;文件为robomimic文件夹中的examples/notebooks/run_policy.ipynb 本文采用pycharm调试 该脚本用于在环境中评估策略&#xff0c;主要包括从model zoo下载checkpoi…

【web开发】Spring Boot 快速搭建Web项目(三)

Date: 2024.08.31 18:01:20 author: lijianzhan 简述&#xff1a;根据上篇原文Spring Boot 快速搭建Web项目&#xff08;二&#xff09;&#xff0c;由于已经搭建好项目初始的框架&#xff0c;以及自动创建了一个启动类文件&#xff08;TestWebApplication.java&#xff09; …

【Python】Daphne:Django 异步服务的桥梁

Daphne 是 Django Channels 项目的一部分&#xff0c;专门用于为 Django 提供支持 HTTP、WebSocket、HTTP2 和 ASGI 协议的异步服务器。Daphne 是一个开源的 Python 异步服务器&#xff0c;它可以帮助开发者运行异步应用程序&#xff0c;并且非常适合与 Django Channels 一起使…

电子电路的基础知识

电子电路是现代电子技术的基础&#xff0c;由电子元件&#xff08;如电阻、电容、电感、二极管、晶体管等&#xff09;和无线电元件通过一定方式连接而成的电路系统。 以下是对电子电路的详细概述&#xff1a; 一、定义与分类 定义&#xff1a;电子电路是指由电子器件和有关无…

解压视频素材下载网站推荐

在制作抖音小说推文或其他短视频时&#xff0c;找到合适的解压视频素材非常重要。以下是几个推荐的网站&#xff0c;可以帮助你轻松下载高质量的解压视频素材&#xff1a; 蛙学网 蛙学网是国内顶尖的短视频素材网站&#xff0c;提供大量4K高清无水印的解压视频素材&#xff0c;…

【记录】Excel|不允许的操作:合并或隐藏单元格出现的问题列表及解决方案

人话说在前&#xff1a;这篇的内容是2022年5月写的&#xff0c;当时碰到了要批量处理数据的情况&#xff0c;但是又不知道数据为啥一直报错报错报错&#xff0c;说不允许我操作&#xff0c;最终发现是因为存在隐藏的列或行&#xff0c;于是就很无语地写了博客&#xff0c;但内容…

如何使用Flux+lora进行AI模型文字生成图片

目录 概要 前期准备 部署安装与运行 1. 部署ComfyUI 本篇的模型部署是在ComfyUI的基础上进行&#xff0c;如果没有部署过ComfyUI&#xff0c;请按照下面流程先进行部署&#xff0c;如已安装请跳过该步&#xff1a; &#xff08;1&#xff09;使用命令克隆 ComfyUI &…

【友元补充】【动态链接补充】

友元 友元的目的是让一个函数或者类&#xff0c;访问另一个类中的私有成员。 友元的关键字friend是一个修饰符。 友元分为友元类和友元函数 1.全局函数作友元 2.类作友元 3.类的一个成员函数作友元 好处&#xff1a;可以通过友元在类外访问类内的私有和受保护类型的成员 坏处…

Python画笔案例-068 绘制漂亮米

1、绘制漂亮米 通过 python 的turtle 库绘制 漂亮米,如下图: 2、实现代码 绘制 漂亮米,以下为实现代码: """漂亮米.py注意亮度为0.5的时候最鲜艳本程序需要coloradd模块支持,安装方法:pip install coloradd程序运行需要很长时间,请耐心等待。可以把窗口最小…

智能Ai语音机器人的应用价值有哪些?

随着时间的推移&#xff0c;人工智能的发展越来越成熟&#xff0c;智能时代也离人们越来越近&#xff0c;近几年人工智能越来越火爆&#xff0c;人工智能的应用已经开始渗透到各行各业&#xff0c;与生活交融&#xff0c;成为人们无法拒绝&#xff0c;无法失去的一个重要存在。…

医疗大数据安全与隐私保护:数据分类分级的基石作用

医疗行业在数字化转型中迅猛发展&#xff0c;医疗大数据作为核心驱动力&#xff0c;深刻改变医疗服务的模式与效率。它不仅促进医疗信息的流通与共享&#xff0c;推动个性化、精准化的医疗服务新生态。同时&#xff0c;也在提升医疗服务质量、优化医疗资源配置等方面展现巨大潜…

Spring Ioc底层原理代码详细解释

文章目录 概要根据需求编写XML文件&#xff0c;配置需要创建的bean编写程序读取XML文件&#xff0c;获取bean相关信息&#xff0c;类&#xff0c;属性&#xff0c;id前提知识点Dom4j根据第二步获取到的信息&#xff0c;结合反射机制动态创建对象&#xff0c;同时完成属性赋值将…

蓝桥杯【物联网】零基础到国奖之路:十二. TIM

蓝桥杯【物联网】零基础到国奖之路:十二. TIM 第一节 理论知识第二节 cubemx配置 第一节 理论知识 STM32L071xx器件包括4个通用定时器、1个低功耗定时器&#xff08;LPTIM&#xff09;、2个基本定时器、2个看门狗定时器和SysTick定时器。 通用定时器&#xff08;TIM2、TIM3、…

Spring Cloud Alibaba-(6)Spring Cloud Gateway【网关】

Spring Cloud Alibaba-&#xff08;1&#xff09;搭建项目环境 Spring Cloud Alibaba-&#xff08;2&#xff09;Nacos【服务注册与发现、配置管理】 Spring Cloud Alibaba-&#xff08;3&#xff09;OpenFeign【服务调用】 Spring Cloud Alibaba-&#xff08;4&#xff09;Sen…