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);
        };
相关推荐
JaguarJack3 小时前
推荐 PHP 属性(Attributes) 简洁读取 API 扩展包
后端·php·服务端
BingoGo3 小时前
推荐 PHP 属性(Attributes) 简洁读取 API 扩展包
php
JaguarJack1 天前
告别 Laravel 缓慢的 Blade!Livewire Blaze 来了,为你的 Laravel 性能提速
后端·php·laravel
郑州光合科技余经理2 天前
代码展示:PHP搭建海外版外卖系统源码解析
java·开发语言·前端·后端·系统架构·uni-app·php
feifeigo1232 天前
matlab画图工具
开发语言·matlab
dustcell.2 天前
haproxy七层代理
java·开发语言·前端
norlan_jame2 天前
C-PHY与D-PHY差异
c语言·开发语言
多恩Stone2 天前
【C++入门扫盲1】C++ 与 Python:类型、编译器/解释器与 CPU 的关系
开发语言·c++·人工智能·python·算法·3d·aigc
QQ4022054962 天前
Python+django+vue3预制菜半成品配菜平台
开发语言·python·django
QQ5110082852 天前
python+springboot+django/flask的校园资料分享系统
spring boot·python·django·flask·node.js·php