解决editor.md+SpringBoot前后端分离上传图片到阿里云OOS跨域等问题

本文涉及的产品
系统运维管理,不限时长
简介: 解决editor.md+SpringBoot前后端分离上传图片到阿里云OOS跨域等问题


最终代码:

一、分析遇到的问题:

在上传图片的时候会显示跨域的问题

后端也配置了跨域的问题

@RestController
@RequestMapping("/rest/agriculture/productController")
@Api("商品管理")
@CrossOrigin
public class ProductController

很明显不是后端的问题,其他的图片都可以进行上传,如下,唯独使用editor.md无法进行上传。

二、解决问题

js配置如下:

//初始化Markdown的编辑区
var testEditor = editormd({
   id      : "test-editormd",
   width   : "100%",
   height  : 640,
   syncScrolling : "single",
   path    : "res/editormd/lib/",
   placeholder : "请填写商品的详细描述信息",
   emoji:true,
   /**上传图片相关配置如下*/
   imageUpload       : true
   ,imageFormats      : ["jpg", "jpeg", "gif", "png", "bmp", "webp"]
   ,saveHTMLToTextarea: true//注意:这个配置,方便post提交表单
   ,crossDomainUpload : true
   ,imageUploadURL    : ServerIP+"/rest/agriculture/productController/addProductImage"//上传图片的的地址
});

关键代码:

/**上传图片相关配置如下*/
   imageUpload       : true
   ,imageFormats      : ["jpg", "jpeg", "gif", "png", "bmp", "webp"]
   ,saveHTMLToTextarea: true//注意:这个配置,方便post提交表单
   ,crossDomainUpload : true
   ,imageUploadURL    : ServerIP+"/rest/agriculture/productController/addProductImage"//上传图片的的地址

后端代码:

String homeDisplayDrawingImageUrl = ossUtil.checkImage(attach); 此代码只是我封装的上传倒阿里云OOS的一个工具类。可以忽略,你可以保存到自己的本地。如果你想保存到本地的话,可以参考我附加的文章地址,查看即可解决。

/**
     * 上传商品简介内容中的插入的单张图
     * @param attach
     * @return
     */
    @ResponseBody
    @RequestMapping(value = "/addProductImage", method = RequestMethod.POST)
    @ApiOperation("上传商品简介内容中的插入的单张图")
    public String addProductImage(@RequestParam(value = "editormd-image-file", required = false) MultipartFile attach) {
        JSONObject jsonObject=new JSONObject();
        //上传商品简介内容中的,单张图 
        String homeDisplayDrawingImageUrl = ossUtil.checkImage(attach); 
        try {
            // 下面response返回的json格式是editor.md所限制的,规范输出就OK
            jsonObject.put("success", 1);
            jsonObject.put("message", "上传成功");
            jsonObject.put("url", homeDisplayDrawingImageUrl);
        } catch (Exception e) {
            jsonObject.put("success", 0);
        }
        System.out.println(jsonObject.toString());
        return jsonObject.toString();
    }

至于传值为什么要这样写:editormd-image-file

@RequestParam(value = "editormd-image-file", required = false) MultipartFile attach

可以打开前端,使用控制台看一下这个的name,就是这个;如果想改的话,就去改源代码了。

解决问题的重要代码:

需要找到admin/res/editormd/plugins/image-dialog/image-dialog.js 这个js文件,因为要修改这的源代码,可以根据自己项目的路径参考我的地址来找到。

原来的代码:

var dialogContent = ( (settings.imageUpload) ? "<form action=\"" + action +"\" target=\"" + iframeName + "\" method=\"post\" enctype=\"multipart/form-data\" class=\"" + classPrefix + "form\">" : "<div class=\"" + classPrefix + "form\">" ) +
( (settings.imageUpload) ? "<iframe name=\"" + iframeName + "\" id=\"" + iframeName + "\" guid=\"" + guid + "\"></iframe>" : "" ) +
     "<label>" + imageLang.url + "</label>" +
     "<input type=\"text\" data-url />" + (function(){
         return (settings.imageUpload) ? "<div class=\"" + classPrefix + "file-input\">" +
                                             "<input type=\"file\" name=\"" + classPrefix + "image-file\" accept=\"image/!*\" />" +
                                             "<input type=\"submit\" value=\"" + imageLang.uploadButton + "\" />" +
                                         "</div>" : "";
     })() +
     "<br/>" +
     "<label>" + imageLang.alt + "</label>" +
     "<input type=\"text\" value=\"" + selection + "\" data-alt />" +
     "<br/>" +
     "<label>" + imageLang.link + "</label>" +
     "<input type=\"text\" value=\"http://\" data-link />" +
     "<br/>" +
 ( (settings.imageUpload) ? "</form>" : "</div>");

修改成:

var dialogContent = ( (settings.imageUpload) ? "<form action=\"#\" target=\"" + iframeName + "\" method=\"post\" enctype=\"multipart/form-data\" class=\"" + classPrefix + "form\">" : "<div class=\"" + classPrefix + "form\">" ) +
 ( (settings.imageUpload) ? "<iframe name=\"" + iframeName + "\" id=\"" + iframeName + "\" guid=\"" + guid + "\"></iframe>" : "" ) +
 "<label>" + imageLang.url + "</label>" +
 "<input type=\"text\" data-url />" + (function(){
     return (settings.imageUpload) ? "<div class=\"" + classPrefix + "file-input\">" +
         "<input type=\"file\" name=\"" + classPrefix + "image-file\" id=\"" + classPrefix + "image-file\" accept=\"image/!*\" />" +
         "<input type=\"submit\" value=\"" + imageLang.uploadButton + "\" />" +
         "</div>" : "";
 })() +
 "<br/>" +
 "<label>" + imageLang.alt + "</label>" +
 "<input type=\"text\" value=\"" + selection + "\" data-alt />" +
 "<br/>" +
 "<label>" + imageLang.link + "</label>" +
 "<input type=\"text\" value=\"http://\" data-link />" +
 "<br/>" +
 ( (settings.imageUpload) ? "</form>" : "</div>");

原来的:

uploadIframe.onload = function() {
   loading(false);
    var body = (uploadIframe.contentWindow ? uploadIframe.contentWindow : uploadIframe.contentDocument).document.body;
    var json = (body.innerText) ? body.innerText : ( (body.textContent) ? body.textContent : null);
    json = (typeof JSON.parse !== "undefined") ? JSON.parse(json) : eval("(" + json + ")");
    console.log(json);
    if(!settings.crossDomainUpload)
    {
      if (json.success === 1)
      {
          dialog.find("[data-url]").val(json.url);
      }
      else
      {
          alert(json.message);
      }
    }
    return false;
};

修改成:

uploadIframe.onload = function() {
      loading(false);
       //这是我个人写法
      var formData = new FormData();
       formData.append("editormd-image-file",$("#editormd-image-file")[0].files[0]);
       var action = settings.imageUploadURL + (settings.imageUploadURL.indexOf("?") >= 0 ? "&" : "?") + "guid=" + guid;
       console.log(formData);
       $.ajax({
           type:"post",
           url:action,
           data:formData,
           dataType:"json",
           async:false,
           processData : false, // 使数据不做处理
           contentType : false, // 不要设置Content-Type请求头
           success:function(data){
               // 成功拿到结果放到这个函数 data就是拿到的结果
               console.log(data);
               if(data.success == 1){
                   console.log(data.message);
                   dialog.find("[data-url]").val(data.url);
               }else{
                   alert(data.message);
               }
           },
       });
       return false;
};

全部js文件代码:

/*!
 * Image (upload) dialog plugin for Editor.md
 *
 * @file        image-dialog.js
 * @author      pandao
 * @version     1.3.4
 * @updateTime  2015-06-09
 * {@link       https://github.com/pandao/editor.md}
 * @license     MIT
 */
(function() {
    var factory = function (exports) {
    var pluginName   = "image-dialog";
    exports.fn.imageDialog = function() {
            var _this       = this;
            var cm          = this.cm;
            var lang        = this.lang;
            var editor      = this.editor;
            var settings    = this.settings;
            var cursor      = cm.getCursor();
            var selection   = cm.getSelection();
            var imageLang   = lang.dialog.image;
            var classPrefix = this.classPrefix;
            var iframeName  = classPrefix + "image-iframe";
      var dialogName  = classPrefix + pluginName, dialog;
      cm.focus();
            var loading = function(show) {
                var _loading = dialog.find("." + classPrefix + "dialog-mask");
                _loading[(show) ? "show" : "hide"]();
            };
            if (editor.find("." + dialogName).length < 1)
            {
                var guid   = (new Date).getTime();
                var action = settings.imageUploadURL + (settings.imageUploadURL.indexOf("?") >= 0 ? "&" : "?") + "guid=" + guid;
                if (settings.crossDomainUpload)
                {
                    action += "&callback=" + settings.uploadCallbackURL + "&dialog_id=editormd-image-dialog-" + guid;
                }
              /*  var dialogContent = ( (settings.imageUpload) ? "<form action=\"" + action +"\" target=\"" + iframeName + "\" method=\"post\" enctype=\"multipart/form-data\" class=\"" + classPrefix + "form\">" : "<div class=\"" + classPrefix + "form\">" ) +
                                        ( (settings.imageUpload) ? "<iframe name=\"" + iframeName + "\" id=\"" + iframeName + "\" guid=\"" + guid + "\"></iframe>" : "" ) +
                                        "<label>" + imageLang.url + "</label>" +
                                        "<input type=\"text\" data-url />" + (function(){
                                            return (settings.imageUpload) ? "<div class=\"" + classPrefix + "file-input\">" +
                                                                                "<input type=\"file\" name=\"" + classPrefix + "image-file\" accept=\"image/!*\" />" +
                                                                                "<input type=\"submit\" value=\"" + imageLang.uploadButton + "\" />" +
                                                                            "</div>" : "";
                                        })() +
                                        "<br/>" +
                                        "<label>" + imageLang.alt + "</label>" +
                                        "<input type=\"text\" value=\"" + selection + "\" data-alt />" +
                                        "<br/>" +
                                        "<label>" + imageLang.link + "</label>" +
                                        "<input type=\"text\" value=\"http://\" data-link />" +
                                        "<br/>" +
                                    ( (settings.imageUpload) ? "</form>" : "</div>");*/
                //这是我个人写法
                var dialogContent = ( (settings.imageUpload) ? "<form action=\"#\" target=\"" + iframeName + "\" method=\"post\" enctype=\"multipart/form-data\" class=\"" + classPrefix + "form\">" : "<div class=\"" + classPrefix + "form\">" ) +
                    ( (settings.imageUpload) ? "<iframe name=\"" + iframeName + "\" id=\"" + iframeName + "\" guid=\"" + guid + "\"></iframe>" : "" ) +
                    "<label>" + imageLang.url + "</label>" +
                    "<input type=\"text\" data-url />" + (function(){
                        return (settings.imageUpload) ? "<div class=\"" + classPrefix + "file-input\">" +
                            "<input type=\"file\" name=\"" + classPrefix + "image-file\" id=\"" + classPrefix + "image-file\" accept=\"image/!*\" />" +
                            "<input type=\"submit\" value=\"" + imageLang.uploadButton + "\" />" +
                            "</div>" : "";
                    })() +
                    "<br/>" +
                    "<label>" + imageLang.alt + "</label>" +
                    "<input type=\"text\" value=\"" + selection + "\" data-alt />" +
                    "<br/>" +
                    "<label>" + imageLang.link + "</label>" +
                    "<input type=\"text\" value=\"http://\" data-link />" +
                    "<br/>" +
                    ( (settings.imageUpload) ? "</form>" : "</div>");
        //这个是作者注释掉的,不知道干啥的 忽略即可
                //var imageFooterHTML = "<button class=\"" + classPrefix + "btn " + classPrefix + "image-manager-btn\" style=\"float:left;\">" + imageLang.managerButton + "</button>";
                dialog = this.createDialog({
                    title      : imageLang.title,
                    width      : (settings.imageUpload) ? 465 : 380,
                    height     : 254,
                    name       : dialogName,
                    content    : dialogContent,
                    mask       : settings.dialogShowMask,
                    drag       : settings.dialogDraggable,
                    lockScreen : settings.dialogLockScreen,
                    maskStyle  : {
                        opacity         : settings.dialogMaskOpacity,
                        backgroundColor : settings.dialogMaskBgColor
                    },
                    buttons : {
                        enter : [lang.buttons.enter, function() {
                            var url  = this.find("[data-url]").val();
                            var alt  = this.find("[data-alt]").val();
                            var link = this.find("[data-link]").val();
                            if (url === "")
                            {
                                alert(imageLang.imageURLEmpty);
                                return false;
                            }
              var altAttr = (alt !== "") ? " \"" + alt + "\"" : "";
                            if (link === "" || link === "http://")
                            {
                                cm.replaceSelection("![" + alt + "](" + url + altAttr + ")");
                            }
                            else
                            {
                                cm.replaceSelection("[![" + alt + "](" + url + altAttr + ")](" + link + altAttr + ")");
                            }
                            if (alt === "") {
                                cm.setCursor(cursor.line, cursor.ch + 2);
                            }
                            this.hide().lockScreen(false).hideMask();
                            //删除对话框
                            this.remove();
                            return false;
                        }],
                        cancel : [lang.buttons.cancel, function() {
                            this.hide().lockScreen(false).hideMask();
                            //删除对话框
                            this.remove();
                            return false;
                        }]
                    }
                });
                dialog.attr("id", classPrefix + "image-dialog-" + guid);
        if (!settings.imageUpload) {
                    return ;
                }
        var fileInput  = dialog.find("[name=\"" + classPrefix + "image-file\"]");
        fileInput.bind("change", function() {
          var fileName  = fileInput.val();
          var isImage   = new RegExp("(\\.(" + settings.imageFormats.join("|") + "))$", "i"); // /(\.(webp|jpg|jpeg|gif|bmp|png))$/
          if (fileName === "")
          {
            alert(imageLang.uploadFileEmpty);
                        return false;
          }
                    if (!isImage.test(fileName))
          {
            alert(imageLang.formatNotAllowed + settings.imageFormats.join(", "));
                        return false;
          }
                    loading(true);
                    var submitHandler = function() {
                        var uploadIframe = document.getElementById(iframeName);
                        uploadIframe.onload = function() {
                            loading(false);
                            /*var body = (uploadIframe.contentWindow ? uploadIframe.contentWindow : uploadIframe.contentDocument).document.body;
                            var json = (body.innerText) ? body.innerText : ( (body.textContent) ? body.textContent : null);
                            json = (typeof JSON.parse !== "undefined") ? JSON.parse(json) : eval("(" + json + ")");
                            console.log(json);
                            if(!settings.crossDomainUpload)
                            {
                              if (json.success === 1)
                              {
                                  dialog.find("[data-url]").val(json.url);
                              }
                              else
                              {
                                  alert(json.message);
                              }
                            }
                            return false;*/
                                //这是我个人写法
                               var formData = new FormData();
                                formData.append("editormd-image-file",$("#editormd-image-file")[0].files[0]);
                                var action = settings.imageUploadURL + (settings.imageUploadURL.indexOf("?") >= 0 ? "&" : "?") + "guid=" + guid;
                                console.log(formData);
                                $.ajax({
                                    type:"post",
                                    url:action,
                                    data:formData,
                                    dataType:"json",
                                    async:false,
                                    processData : false, // 使数据不做处理
                                    contentType : false, // 不要设置Content-Type请求头
                                    success:function(data){
                                        // 成功拿到结果放到这个函数 data就是拿到的结果
                                        console.log(data);
                                        if(data.success == 1){
                                            console.log(data.message);
                                            dialog.find("[data-url]").val(data.url);
                                        }else{
                                            alert(data.message);
                                        }
                                    },
                                });
                                return false;
                        };
                    };
                    dialog.find("[type=\"submit\"]").bind("click", submitHandler).trigger("click");
        });
            }
      dialog = editor.find("." + dialogName);
      dialog.find("[type=\"text\"]").val("");
      dialog.find("[type=\"file\"]").val("");
      dialog.find("[data-link]").val("http://");
      this.dialogShowMask(dialog);
      this.dialogLockScreen();
      dialog.show();
    };
  };
  // CommonJS/Node.js
  if (typeof require === "function" && typeof exports === "object" && typeof module === "object")
    {
        module.exports = factory;
    }
  else if (typeof define === "function")  // AMD/CMD/Sea.js
    {
    if (define.amd) { // for Require.js
      define(["editormd"], function(editormd) {
                factory(editormd);
            });
    } else { // for Sea.js
      define(function(require) {
                var editormd = require("./../../editormd");
                factory(editormd);
            });
    }
  }
  else
  {
        factory(window.editormd);
  }
})();

三、效果

可参考地址:

https://blog.csdn.net/ELOVINFG/article/details/103048813

https://www.cnblogs.com/softidea/p/7808214.html

四、快看,小郑有话对你说

如果对你有帮助,可以分享给你身边的朋友。或者给俺点个大大的赞和大大的评论,点赞和评论就是给我最大的支持,感谢。

水平有限,难免会有疏漏或者书写不合理的地方,欢迎交流讨论。

目录
相关文章
|
29天前
|
JavaScript 前端开发 Java
springboot解决js前端跨域问题,javascript跨域问题解决
本文介绍了如何在Spring Boot项目中编写Filter过滤器以处理跨域问题,并通过一个示例展示了使用JavaScript进行跨域请求的方法。首先,在Spring Boot应用中添加一个实现了`Filter`接口的类,设置响应头允许所有来源的跨域请求。接着,通过一个简单的HTML页面和jQuery发送AJAX请求到指定URL,验证跨域请求是否成功。文中还提供了请求成功的响应数据样例及请求效果截图。
springboot解决js前端跨域问题,javascript跨域问题解决
|
22天前
|
安全 Java 应用服务中间件
SpringBoot:CORS是什么?SpringBoot如何解决跨域问题?
CORS是Web开发中常见且重要的机制,SpringBoot通过提供注解、全局配置和过滤器等多种方式来解决跨域问题。选择适合的方式可以帮助开发者轻松处理跨域请求,提高应用的灵活性和安全性。
48 2
|
29天前
|
前端开发 安全 Java
springboot解决跨域问题
跨域问题指前端调用与后端接口不在同一域名或端口时产生的安全限制。本文介绍两种在Spring Boot中解决跨域问题的方法:一是通过配置CorsFilter,二是实现WebMvcConfigurer接口。配置完成后重启项目即可生效。作者:博笙困了。来源:稀土掘金。
|
29天前
|
安全 JavaScript Java
SpringBoot解决跨域最佳实践
本文介绍了跨域问题的起因及最佳实践,重点讲解了SpringBoot中如何利用`CorsFilter`解决跨域问题。首先解释了由于浏览器的同源策略限制导致的跨域现象,然后提出了在服务端入口处解决跨域问题的建议,最后详细展示了三种SpringBoot中配置跨域的方法:使用默认配置、自定义配置规则以及通过配置文件管理跨域设置,以适应不同的应用场景。
|
29天前
|
前端开发 安全 JavaScript
SpringBoot 如何解决跨域问题?
本文深入探讨了Spring Boot解决跨域问题的方法,包括全局配置CORS、使用@CrossOrigin注解和自定义过滤器,提供了详细的代码示例和分析,帮助开发者有效应对Web开发中的跨域挑战。
|
7月前
|
弹性计算 运维 Linux
Docker环境如何配置?使用阿里云OOS一步搞定!
阿里云OOS简化了ECS上应用部署,提供Docker一键安装服务。支持多种操作系统,包括Alibaba Cloud Linux、CentOS、Ubuntu、Debian和Windows Server。要安装Docker,用户只需在OOS扩展程序中选择并确认实例,执行安装。OOS扩展程序还支持Java、Python等开发环境及宝塔面板、WordPress等应用的快速配置,提升运维效率,让云资源管理更便捷。
Docker环境如何配置?使用阿里云OOS一步搞定!
|
2月前
|
JavaScript 前端开发 Java
解决跨域问题大集合:vue-cli项目 和 java/springboot(6种方式) 两端解决(完美解决)
这篇文章详细介绍了如何在前端Vue项目和后端Spring Boot项目中通过多种方式解决跨域问题。
400 1
解决跨域问题大集合:vue-cli项目 和 java/springboot(6种方式) 两端解决(完美解决)
|
2月前
|
Java 数据库连接 API
springBoot:后端解决跨域&Mybatis-Plus&SwaggerUI&代码生成器 (四)
本文介绍了后端解决跨域问题的方法及Mybatis-Plus的配置与使用。首先通过创建`CorsConfig`类并设置相关参数来实现跨域请求处理。接着,详细描述了如何引入Mybatis-Plus插件,包括配置`MybatisPlusConfig`类、定义Mapper接口以及Service层。此外,还展示了如何配置分页查询功能,并引入SwaggerUI进行API文档生成。最后,提供了代码生成器的配置示例,帮助快速生成项目所需的基础代码。
163 1
|
6月前
|
前端开发 安全 JavaScript
Spring Boot2 系列教程(十四)CORS 解决跨域问题
Spring Boot2 系列教程(十四)CORS 解决跨域问题
|
4月前
|
安全 前端开发 Java
Web端系统开发解决跨域问题——以Java SpringBoot框架配置Cors为例
在Web安全上下文中,源(Origin)是指一个URL的协议、域名和端口号的组合。这三个部分共同定义了资源的来源,浏览器会根据这些信息来判断两个资源是否属于同一源。例如,https://www.example.com:443和http://www.example.com虽然域名相同,但由于协议和端口号不同,它们被视为不同的源。同源(Same-Origin)是指两个URL的协议、域名和端口号完全相同。只有当这些条件都满足时,浏览器才认为这两个资源来自同一源,从而允许它们之间的交互操作。
Web端系统开发解决跨域问题——以Java SpringBoot框架配置Cors为例