首页 > 其他分享 >CKeditor5实现图片上传

CKeditor5实现图片上传

时间:2023-11-02 18:01:41浏览次数:43  
标签:const url writer upload editor imageElement CKeditor5 上传 图片

// 2019-3-27 更新,最初发在这里只是记录一下 CKeditor5 的发布,当时的版本还是 1.0.0-alpha.1,截止今日,已经更新为 v12.0.0,之前的一些方法已经不太兼容,特更新如下,希望能帮助到大家。

CKeditor5 相比 CKeditor4 更轻量级,可以按需定制很灵活,CKeditor5 是彻头彻尾的重写,支持移动端、支持按需定制,灵活的插件机制等。CKeditor5 和 CKeditor4 是完全不兼容的,使用方式也有许多不同。

在我们的项目中,使用 CKeditor5 实现了文章发布、图片上传、图片拖拽上传、剪贴板粘贴上传、以及复制图文内容实现远程图片自动本地化。

首先安装 CKeditor5 和 axios 库(上传需要)

yarn add @ckeditor/ckeditor5-build-classic
yarn add axios

相关代码

// Editor.js
import ClassicEditor from '@ckeditor/ckeditor5-build-classic'
import '@ckeditor/ckeditor5-build-classic/build/translations/zh-cn.js'
import CatchRemoteImage from './CatchRemoteImage'

export default class Editor {

    constructor(element, config) {
        let defaultConfig = {
            toolbar: ['heading', '|', 'bold', 'italic', 'blockQuote', 'bulletedList', 'numberedList', 'link', 'imageUpload', 'undo', 'redo'],
            language: 'zh-cn',
            ckfinder: {
                uploadUrl: '/upload'
            }
        };

        this.element = element;
        this.config = Object.assign(defaultConfig, config)
    }

    static create(element, config) {
        const editor = new this(element, config);

        ClassicEditor
            .create(editor.element, editor.config)
            .then(editor => {
                const doc = editor.model.document;

                // 远程图片上传
                // 参考 https://github.com/ckeditor/ckeditor5-image/blob/master/src/imageupload/imageuploadediting.js#L78
                editor.model.document.on('change', () => {
                    const changes = doc.differ.getChanges();

                    for (const entry of changes) {
                        if (entry.type === 'insert' && entry.name === 'image') {
                            const item = entry.position.nodeAfter;

                            // Check if the image element still has upload id.
                            const uploadId = item.getAttribute('uploadId');
                            const uploadStatus = item.getAttribute('uploadStatus');

                            if (!uploadId && !uploadStatus) {
                                CatchRemoteImage(editor, item);
                            }
                        }
                    }
                });
            })
            .catch(error => {
                console.log(error)
            })
    }
};

图文混合内容粘贴后,图片本地化方法脚本:

// CatchRemoteImage.js
import axios from "axios";

export default function (editor, imageElement) {
    const uploadingImage = 'https://www.cshome.com/build/images/uploading.gif';
    const failImage = 'https://www.cshome.com/build/images/upload-fail.jpg';
    const imageUrl = imageElement.getAttribute('src');
    const localDomains = ['cshome.com'];

    const model = editor.model;

    // 检测是否需要上传
    function test(url) {
        if (url.indexOf(location.host) !== -1 || /(^\.)|(^\/)/.test(url)) {
            return true;
        }

        if (localDomains) {
            for (let domain in localDomains) {
                if (localDomains.hasOwnProperty(domain) && url.indexOf(localDomains[domain]) !== -1) {
                    return true;
                }
            }
        }

        return false;
    }

    // 图片上传
    function upload(url) {
        let data = new FormData();
        data.append('url', url);

        return axios.post(
            '/upload-by-url',
            data,
            {
                headers: {
                    'content-type': 'multipart/form-data'
                }
            })
    }

    if (/^https?:/i.test(imageUrl) && !test(imageUrl)) {
        model.enqueueChange('transparent', writer => {
            writer.setAttribute('src', uploadingImage, imageElement);
            writer.setAttribute('uploadStatus', 'uploading', imageElement);
        });

        upload(imageUrl)
            .then(response => {
                model.enqueueChange('transparent', writer => {
                    writer.setAttribute('src', response.data.url, imageElement);
                    writer.setAttribute('uploadStatus', 'complete', imageElement);
                });

                clean();
            })
            .catch(error => {
                model.enqueueChange('transparent', writer => {
                    writer.setAttribute('src', failImage, imageElement);
                });

                clean();
            })
    }

    function clean() {
        model.enqueueChange('transparent', writer => {
            writer.removeAttribute('uploadId', imageElement);
            writer.removeAttribute('uploadStatus', imageElement);
        });
    }
}

使用

Editor.create(document.querySelector('#article_body'), {
    toolbar: ['bold', 'italic', 'blockQuote', 'bulletedList', 'numberedList', 'link', 'imageUpload', 'undo', 'redo'],
});

 

// demo.html
<div id="article_body"></div>

最早的时候,我是使用的 UploadAdapter 方式 ,但是后续的版本直接可以用 ckfinder 来实现,方便了很多。

FileUploadAdapter 的核心是需要实现 upload和 abort方法 ,upload方法需要返回 Promise对象。

上面 ckfinder 接口 /upload 返回数据格式为

{
    uploaded: true,
    url: '图片地址'
}

完成。

 

参考文章:http://blog.ncmem.com/wordpress/2023/11/02/ckeditor5%e5%ae%9e%e7%8e%b0%e5%9b%be%e7%89%87%e4%b8%8a%e4%bc%a0/

欢迎入群一起讨论

 

 

标签:const,url,writer,upload,editor,imageElement,CKeditor5,上传,图片
From: https://www.cnblogs.com/songsu/p/17805942.html

相关文章

  • OFD添加图片水印-JAVA
    写出了一个ofd文件加图片水印的工具类,分享给大家参考。1、引入ofdrw<!--junit--><dependency><groupId>junit</groupId><artifactId>junit</artifactId><version>4.12</version><scope>provided</scope></depende......
  • 如何通过HWebkit库配合Haskell语言采集链家图片
    链家是一个专业提供二手房源、楼盘等信息的网站,需要二手房的朋友,链家可是个首选的资源平台。今天我们将使用HWebkit库编写一个爬虫程序,然后使用Haskell语言来采集链家平台的相关图片,快来学习一下吧。```haskellimportNetwork.HTTP.Webkit--定义代理主机和端口proxyHost::Str......
  • Delphi使用TNetHTTPClient上传文件java接收测试
    Delphi使用TNetHTTPClient上传文件java接收测试上传客户端新建一个应用,拖入一个TButton按扭,一个TMemo多行文件显示框,一个TNetHttpClient,一个OpenDialog文件打开对话框。双击按扭添加代码  uses  System.Net.Mime;procedureTForm1.Button1Click(Sender:TObject);var......
  • vue3项目 - 手写可拖拽带进度监控的文件上传组件
    1.实现原理: 原生的上传文件组件: <inputref="uploadFileRef"style="display:none"type="file"/> 自定义上传区域:  拖拽事件添加(dragover,dragenter,drop),点击事件添加(click)调用原生上传组件的click事件:uploadFileRef.value.click()监听元素上传组件的值回传事件:c......
  • 使用 CKEditor 上传图片, 粘贴屏幕截图
    之前写过wangEditor,那真是好用,文档也清晰,半天就搞定了,无奈没有对应license,只好选择别的。外语一般,阅读理解都靠蒙。CKEditor官方文档看的我云里雾里,国内的博客比较少,经过一天的调试,终于成功了。记录下,欢迎交流。1.下载CKEditor包。 打开samples文件夹下的index.html,确......
  • PHP 合成gif 图片
    方法一:<?phpnamespaceApp\Services\Common;//namespacegifCreator;/***CreateananimatedGIFfrommultipleimages*/classGifcreator{/***@varstringThegifstringsource(old:this->GIF)*/private$gif;/**......
  • ckeditor富文本编辑器的使用和图片上传,复制粘贴图片上传
    项目开发需要用到在线编辑和图片上传,最终讨论使用ckeditor,原因就是其丰富的API。考虑到最新版本ckeditor5可能不够稳定,我们选择使用ckedtior4.9.2版本。官网链接:ckeditor官网特别注意:下面截图中url中的/editor/upload/1?其中的/1是根据自己需求添加不同类型数据上传时候的区分,......
  • 纯前端实现图片验证码
    前言之前业务系统中验证码一直是由后端返回base64与一个验证码的字符串来实现的,想了下,前端其实可以直接canvas实现,减轻服务器压力。实现子组件,允许自定义图片尺寸(默认尺寸为100*40)与验证码刷新时间(默认时间为60秒)。同时暴露绘制验证码方法drawPic(),允许父组件直接调用(......
  • PHP大文件分割上传详解
    这篇文章主要为大家详细介绍了PHP大文件分割上传,PHP分片上传,具有一定的参考价值,感兴趣的小伙伴们可以参考一下服务端为什么不能直接传大文件?跟php.ini里面的几个配置有关upload_max_filesize=2M //PHP最大能接受的文件大小post_max_size=8M //PHP能收到的最大POST值'me......
  • 【PyTorch 卷积】实战自定义的图片归类
    前言        卷积神经网络是一类包含卷积计算且具有深度结构的前馈神经网络,是深度学习的代表算法之一,它通过卷积层、池化层、全连接层等结构,可以有效地处理如时间序列和图片数据等。关于卷积的概念网络上也比较多,这里就不一一描述了。实战为主当然要从实际问题出发,用代码......