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);
        };
相关推荐
秋窗741 分钟前
Mac下Python版本管理,适用于pyenv不起作用的情况
开发语言·python·macos
柯腾啊44 分钟前
VSCode 中使用 Snippets 设置常用代码块
开发语言·前端·javascript·ide·vscode·编辑器·代码片段
CoderIsArt1 小时前
openGL和C#下使用openGL
开发语言·c#
只做开心事2 小时前
C++之特殊类设计
开发语言·c++
宋康2 小时前
C/C++ 指针避坑20条
c语言·开发语言·c++
爱丫爱3 小时前
Python中常见库 PyTorch和Pydantic 讲解
开发语言·pytorch·python
Ryan_Gosling3 小时前
C++-构造函数-接口
开发语言·c++
服务端相声演员3 小时前
Oracle JDK、Open JDK zulu下载地址
java·开发语言
19岁开始学习4 小时前
Go学习-入门
开发语言·学习·golang
青铜念诗4 小时前
python脚本文件设置进程优先级(在.py文件中实现)
开发语言·python