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里面的内容了