UEditor 富文本编辑器表单跨域上传解决方案

  • Post author:
  • Post category:其他


首先看一下

官方说明


这里写图片描述

实际上表单上传是通过iframe实现异步上传的,然后上传成功后页面再去读取iframe里面内容判断是否成功,如果是同域名这样做当然没有问题。但现在很多公司都是把文件存储这块单独做成文件服务器,应用和文件服务器是完全不同的两个域名,甚至有些前后端分离的应用的前端和后端域名都不一样,这时候就出问题了。

因为浏览器的保护机制,在跨域的情况下是不能读取iframe里的内容的。这是为了防止一个网站读取另一个网站里的信息。所以这就造成了UEditor在上传的时候因为读不到iframe内容而提示“上传错误”这种错觉,但实际上已经上传成功了。

好了,现在知道问题是因为页面读不到iframe内容才造成的“上传失败”,那只要让页面能读到iframe内容那就解决。说一下解决思路:因为iframe只有在同域名下才能被读取内容,所以上传成功之后在iframe里重定向到原来域名并显示结果出来就行了。

解决方法参考


参考场景

  • UEditor应用域名:a.com

    • 有一个 UEditor编辑器页面:a.com/ueditor
    • 和一个文件上传结果显示页面:a.com/static/upload_result.html
  • 文件服务器域名:b.com

    • UEditor文件上传地址:b.com/ueditor/upload


实现代码

  • 文件服务器的上传代码: b.com/ueditor/upload(java版)

    关键代码是上传成功后将结果重定向到原域名去

    public void upload(HttpServletRequest request, HttpServletResponse response) throws IOException {
        //这里保存文件代码每个项目的实现方式可能不一样,根据自己的项目框架来实现
        UEditorConfig.setRequest(request);
        String result = new ActionEnter(request).exec();
    
        /* 下面是参数代码 */
        String callbackUrl = request.getParameter("callbackUrl");   //原域名接收结果地址
        //如果有接收结果地址就重定向到该地址
        //这里有个地方要注意的是:如果request.action=config,那这次请求只是前端加载UEditor配置而已,不需要重定向
        if(StringUtils.isNotBlank(callbackUrl) &&
                !"config".equals(request.getParameter("action"))){
            callbackUrl = URLDecoder.decode(callbackUrl, "utf-8");
            if(callbackUrl.indexOf("?") > 0){
                callbackUrl += "&result=" + URLEncoder.encode(result, "utf-8");
            }else{
                callbackUrl += "?result=" + URLEncoder.encode(result, "utf-8");
            }
            response.sendRedirect(callbackUrl);
        }else{
            response.setCharacterEncoding("utf-8");
            response.setHeader("Content-Type", "text/html; charset=utf-8");
            response.getWriter().write(result);
        }
    }
  • 结果显示的html页面:a.com/static/upload_result.html

    这个页面可以做成一个静态页面直接访问

    上传结果会重定向回来这里显示,重定向为地址:

    http://a.com/upload_result?result=jsonStr
<!DOCTYPE html>
<html>
<body></body>
<script>
    function getQueryString(name){
        var reg = new RegExp("(^|&)"+ name +"=([^&]*)(&|$)");
        var r = window.location.search.substr(1).match(reg);
        if(r!=null)return  decodeURIComponent(r[2]); return null;
    }
    //获取上传结果
    var result = getQueryString('result');
    //因为后端经过URLEncoder.encode(result)会莫名多一个"+"号,需要去掉
    result = result.replace(/\+/g,'');
    //将结果显示出来
    document.write(result);
</script>
</html>
  • UEditor编辑器页面:a.com/ueditor

    • 修改 ueditor.config.js 的上传地址,加上重定向地址
window.UEDITOR_CONFIG = {
    serverUrl: 'http/b.com/ueditor/upload?callbackUrl=' + encodeURI(window.ueditorUploadCallbackUrl || '')
    //其它配置...
}
  • ueditor的html页面
<!DOCTYPE html>
<html>
<head>
    <meta charset="UTF-8">
    <title>ueditor跨域上传</title>
    <script type="text/javascript">
        //配置获取上传结果的url
        var ueditorUploadCallbackUrl = 'http://a.com/static/upload_result.html'
    </script>
    <!-- 省略引用相关ueditor.*.js的代码 -->
</head>
<body>
<textarea name="Ueditor" id="Ueditor"></textarea>
</body>
<script>
    window.onload = function(){
        UE.getEditor('Ueditor');
    }
</script>
</html>

好了,做完这几步就可以解决跨域上传的问题了。

关键的步骤是:

– 后端上传成功后的重定向

– 前端准备一个页面接收结果



版权声明:本文为lnkToKing原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。