editor.md编辑器,图片跨域上传,前后端分离

解决思路:

不修改原来的editormd文件

通过猴子补丁(monkey patch)的方式,替换editormd内部的上传方法。例如,找到image-dialog.js中处理上传的函数,保存原函数的引用,然后用自定义函数替换

复制代码
    // 初始化编辑器
    function initEditor() {
        // 保存原始图片上传处理函数
        const originalImageUpload = editormd.prototype.executePlugin;

        // 猴子补丁方式覆盖图片上传处理
        editormd.prototype.executePlugin = function(pluginName, options) {
            if (pluginName === "imageDialog") {
                this.imageUploader = function() {
                    const file = this.files[0];
                    const loading = layer.msg('上传中...', {icon: 16, shade: 0.01});

                    // 创建与现有上传组件一致的FormData
                    const formData = new FormData();
                    formData.append('editormd-image-file', file); // 保持参数名称与现有系统一致
                    formData.append('filetype', 0); // 添加系统要求的参数

                    // 使用原始XMLHttpRequest发送保持请求结构
                    const xhr = new XMLHttpRequest();
                    xhr.open('POST', API.getApiUrl('index/upload'));
                    xhr.setRequestHeader('Authorization', 'Bearer ' + API.getToken());
                    
                    xhr.upload.onprogress = function(e) {
                        if (e.lengthComputable) {
                            const percent = (e.loaded / e.total * 100).toFixed(2) + '%';
                            layer.msg('上传进度: ' + percent, {icon: 16, shade: 0.01});
                        }
                    };

                    xhr.onload = function() {
                        layer.close(loading);
                        try {
                            const res = JSON.parse(xhr.responseText);
                            if (res.success === 1) {
                                // 使用编辑器API插入图片
                                const cursor = this.getCursor();
                                this.replaceSelection(`![](${res.url})`, cursor);
                                layer.msg('上传成功', {icon: 1});
                            } else {
                                layer.msg(res.msg || '上传失败', {icon: 2});
                            }
                        } catch(e) {
                            console.error('解析响应失败:', e);
                            layer.msg('上传失败', {icon: 2});
                        }
                    }.bind(taskEditor); // 绑定编辑器实例上下文

                    xhr.onerror = function() {
                        layer.close(loading);
                        console.error('上传失败:', xhr.statusText);
                        layer.msg('网络错误', {icon: 2});
                    };

                    xhr.send(formData);
                };

                // 保持与Editor.md一致的DOM操作
                const fakeInput = document.createElement('input');
                fakeInput.type = 'file';
                fakeInput.name = 'editormd-image-file';
                fakeInput.accept = "image/*";
                fakeInput.onchange = this.imageUploader.bind(fakeInput);
                fakeInput.click();
                
                return false;
            }
            return originalImageUpload.apply(this, arguments);
        };

        // 继续原有编辑器初始化逻辑
        const editorContainer = $('#taskDescription');
        if (editorContainer.is(':visible')) {
            const isMobile = window.innerWidth <= 768;
            console.log('0000',CONFIG.API.getBaseUrl());
            taskEditor = editormd("taskDescription", {
                width: "100%",
                height: isMobile ? 400 : 500,
                path : "../editormd/lib/",
                toolbarIcons : function() {
                    return window.editormdConfig ? 
                        window.editormdConfig.toolbarIcons : 
                        [
                            "undo", "redo", "|",
                            "bold", "del", "italic", "quote", "ucwords", "uppercase", "lowercase", "|",
                            "h1", "h2", "h3", "h4", "h5", "h6", "|",
                            "list-ul", "list-ol", "hr", "|",
                            "link", "image", "code", "preformatted-text", "code-block", "table", "|",
                            "watch", "preview", "fullscreen", "|",
                            "help"
                        ];
                },
                placeholder: "请详细描述任务需求...",
                saveHTMLToTextarea : true,
                imageUpload : false,
                imageFormats : ["jpg", "jpeg", "gif", "png", "bmp", "webp"],
                imageUploadURL : CONFIG.API.getBaseUrl() + "/index/upload?filetype=0",
                crossDomainUpload: true, // 禁用跨域上传
                tex  : true,
                flowChart : true,
                sequenceDiagram : true,
                emoji : true,
                watch: !isMobile, // 移动端关闭实时预览
                onload : function() {
                    console.log('编辑器加载完成');
                }
            });
        } else {
            setTimeout(initEditor, 500); // 延迟检查
        }
    }

解决办法就是:猴子补丁方式覆盖图片上传处理

复制代码
        // 猴子补丁方式覆盖图片上传处理
        editormd.prototype.executePlugin = function(pluginName, options) {
            if (pluginName === "imageDialog") {
                this.imageUploader = function() {
                    const file = this.files[0];
                    const loading = layer.msg('上传中...', {icon: 16, shade: 0.01});

                    // 创建与现有上传组件一致的FormData
                    const formData = new FormData();
                    formData.append('editormd-image-file', file); // 保持参数名称与现有系统一致
                    formData.append('filetype', 0); // 添加系统要求的参数

                    // 使用原始XMLHttpRequest发送保持请求结构
                    const xhr = new XMLHttpRequest();
                    xhr.open('POST', API.getApiUrl('index/upload'));
                    xhr.setRequestHeader('Authorization', 'Bearer ' + API.getToken());
                    
                    xhr.upload.onprogress = function(e) {
                        if (e.lengthComputable) {
                            const percent = (e.loaded / e.total * 100).toFixed(2) + '%';
                            layer.msg('上传进度: ' + percent, {icon: 16, shade: 0.01});
                        }
                    };

                    xhr.onload = function() {
                        layer.close(loading);
                        try {
                            const res = JSON.parse(xhr.responseText);
                            if (res.success === 1) {
                                // 使用编辑器API插入图片
                                const cursor = this.getCursor();
                                this.replaceSelection(`![](${res.url})`, cursor);
                                layer.msg('上传成功', {icon: 1});
                            } else {
                                layer.msg(res.msg || '上传失败', {icon: 2});
                            }
                        } catch(e) {
                            console.error('解析响应失败:', e);
                            layer.msg('上传失败', {icon: 2});
                        }
                    }.bind(taskEditor); // 绑定编辑器实例上下文

                    xhr.onerror = function() {
                        layer.close(loading);
                        console.error('上传失败:', xhr.statusText);
                        layer.msg('网络错误', {icon: 2});
                    };

                    xhr.send(formData);
                };

                // 保持与Editor.md一致的DOM操作
                const fakeInput = document.createElement('input');
                fakeInput.type = 'file';
                fakeInput.name = 'editormd-image-file';
                fakeInput.accept = "image/*";
                fakeInput.onchange = this.imageUploader.bind(fakeInput);
                fakeInput.click();
                
                return false;
            }
            return originalImageUpload.apply(this, arguments);
        };
相关推荐
techdashen25 分钟前
Go设计取舍之四: map不变时能否并发修改不同value
开发语言·后端·golang
小小小米粒33 分钟前
阿姆达尔定律(Amdahl‘s Law)
java·开发语言
知彼解己34 分钟前
Java 版本演进
java·开发语言·spring boot
风样滴男人哟38 分钟前
PHP特性之反射类ReflectionClass机制
android·开发语言·php
看昭奚恤哭1 小时前
Flutter 布局核心思想
开发语言·javascript·flutter
nvd111 小时前
GCP L4 Passthrough 负载均衡器“假死超时”深度排查复盘
运维·php·负载均衡
眞bilibili1 小时前
如何快速无缝的从 vscode 转向AI编辑器 cursor、kiro、trae 等
人工智能·vscode·编辑器
IsSh9nj6q1 小时前
Python全栈应用搭建神器magic-dash .新版本介绍
开发语言·python·dash
Cachel wood2 小时前
hands-on-modern-rl:动手学强化学习策略梯度reinforce
开发语言·python
山河不见老2 小时前
【Cursor 、Qoder安装问题】Cursor 、Qoder安装卡在“正在准备安装”问题排查及解决
人工智能·windows·编辑器