Ueditor 跨域图片上传

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/zhuyu19911016520/article/details/83419464

ueditor 文档官方地址:http://fex.baidu.com/ueditor/
我在项目中使用Java,所以用ueditor的后台配置为 JSP
如何自定义请求地址,官方文档也有说明

要跨域上传图片需要明白个东西,例如

  • localhost:8080是ueditor页面,(主服务)
  • localhost:2000是图片上传服务 (上传服务)

不需要修改ueditor的很多js文件,只需要改 ueditor.all.js、config.json文件,再写一个单独图片上传服务,如果是多图上传,则直接返回符合格式的 rest json数据,如果是单图,则在主服务中写一个UeController控制器,添加一个action,接收上传服务重定向过来的数据

在localhost:8080项目下的 ueditor.all.js 的最下方,添加如下代码:

//这里的action就是 jsp/config.json中imageActionName配置的值
UE.Editor.prototype.getActionUrl = function(action) {
    if (action == 'uploadimage' || action == 'uploadscrawl' || action == 'uploadimage') {
        return 'http://localhost:2000/upload/ueupload';//这就是自定义的图片上传路径
    } else if (action == 'uploadvideo') {
        return 'http://localhost:2000/upload/videoupload';
    } else {
        return this._bkGetActionUrl.call(this, action);
    }
}

在localhost:2000项目,上传服务中需要返回 ueditor 能接收的数据格式,格式如下:

UEditorDto.class
{
    "state": "SUCCESS",
    "url": "upload/demo.jpg",
    "title": "demo.jpg",
    "type" : ".jpg"
    "original": "demo.jpg"
}

上传服务,怎么把图片接收,写到本地,然后返回图片的路径,请自行实现,提供java版实现,代码中issimpleupload参数与response.sendRedirect重定向会有说明,此方法通过判断issimpleupload参数分别针对,单图片与多图片上传,提供数据返回,如果是多图片则直接以rest数据返回,如果是单图片,则 response 重定向到 localhost:8080/ueRedirect?json=(rest数据)的控制器上,由该控制器返回数据,来解决 iframe 跨域无法获取返回数据的问题

/**
     * uedtor文件上传
     */
    @RequestMapping(value = "/upload/ueUpload", method = RequestMethod.POST ,produces = MediaType.APPLICATION_JSON_VALUE)
    public UEditorDto ueUpload(HttpServletRequest request, HttpServletResponse response) {
        UEditorDto dto = UEditorDto.getDefaultInstance();
        dto.setState(UEditorDto.Fail);
        String issimpleupload = request.getParameter("issimpleupload"); //只有单图片上传才有此参数
        String json = "";
        try {
            List<MultipartFile> files = ((MultipartHttpServletRequest) request).getFiles("upfile");
            for (int i = 0; i < files.size(); ++i) {
                if (files.get(i) != null) {
                    byte[] bytes = files.get(i).getBytes();
                    String filename = files.get(i).getOriginalFilename();
                    int r = (int) ((Math.random() * 9 + 1) * 100000);
                    String attachId = dateFormat.format(new Date()) + String.valueOf(r).substring(0, 4);
                    String ext = filename.substring(filename.lastIndexOf("."), filename.length()); //后缀名
                    String newFilename = (attachId + ext).toLowerCase();                               //新文件名
                    //保存文件
                    String attachPath = "uploadfiles/" + ueRootPathFormate.format(new Date());
                    String savePath = getRootPath(attachPath) + newFilename;
                    File fileToSave = new File(savePath);
                    FileCopyUtils.copy(bytes, fileToSave);

                    //System.out.println("save file path :" + fileToSave.getAbsolutePath());
                    fileToSave = null;

                    dto.setUrl(attachPath + newFilename);
                    dto.setTitle(newFilename);
                    dto.setOriginal(filename);
                    dto.setType(ext);
                    dto.setState(UEditorDto.Success);
                    response.setHeader("Access-Control-Allow-Origin", "*");//设置该图片允许跨域访问
                    response.setHeader("Access-Control-Allow-Headers", "X-Requested-With,X_Requested_With");//设置允许的跨域header
                    response.setContentType("application/json;charset=utf-8");
                    //如果是单图片,则重定向到旅咖汇后台,否则是多图片,则直接返回rest的数据
                    if(issimpleupload != null && issimpleupload.equals("true")){
                        json = URLEncoder.encode(JSON.toJSONString(dto) , "utf-8") ;
                        response.sendRedirect("localhost:8080/ueRedirect?json=" + json);
                    }
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        //图片,则直接返回rest的数据
        return dto;
    }

localhost:8080项目接收localhost:2000上传服务重定向过来的数据,再输出出来,这样localhost:8080项目ueditor单图片iframe上传后,就能拿到数据了

@Controller
public class UeditorController {
   protected HttpServletRequest request;
   protected HttpServletResponse response;
   @ModelAttribute
    public void setReqAndRes(HttpServletRequest request, HttpServletResponse response) {
        this.request = request;
        this.response = response;
        response.setHeader("Access-Control-Allow-Origin", "*");
        response.setHeader("Access-Control-Allow-Headers", "Authentication");
    }
    //ueditor单图片上传时,是iframe跨域上传,不能从uploadservce服务直接取到数据,需要把数据重定向到当前域下,再转发给ueditor的回调函数,iframe才能获取到数据
    @RequestMapping("/ueRedirect")
    @Authority(AuthorityType.NoValidate)
    public void ue(HttpServletRequest request, HttpServletResponse response){
        try {
            String json = request.getParameter("json");
            PrintWriter out = response.getWriter();
            out.write(json);
            out.flush();
            out.close();
        }catch (Exception e){
            e.printStackTrace();
        }
    }

}

issimpleupload 参数怎么加,在 ueditor.all.js 中,搜索 <input id="edui_input_ 这段,然后在后面且< /form>之前加上一个隐藏域,这样,当单图上传时,就会把issimpleupload 当作参数传到上传,然后进行判断,如果是单图上传,就 response.sendRedirect重定向到 localhost:8080/ueRedirect?json=(ueditor需要的数据),并加上数据,这样 iframe 就能获取到数据了

<input type="hidden" name="issimpleupload" value="true" />

在这里插入图片描述

单图上传,重定向到localhost:8080/ueRedirect下后,iframe接收到的数据
在这里插入图片描述

多图上传,由上传服务localhost:2000直接返回符合格式的rest json数据即可
在这里插入图片描述

原理:单图它是提交到iframe去上传,然后监控iframe加载完成后js获取iframe里面的内容也就是json结果来得到图片上传结果。而跨域上传iframe里面的页面和当前页面不是同一个域名就获取不到json了,官方说暂时不支持

其实也简单,就是文件服务器 localhost:2000 上传成功后,重定向到 localhost:8080 下面来的ueRedirect action中来,把结果传递到这个页面上,再输出来,这样iframe就在同一个域名上了,js就能直接获取iframe里面的内容了

猜你喜欢

转载自blog.csdn.net/zhuyu19911016520/article/details/83419464