使用cropper进行图片裁剪上传的时候,参考了相关资料,前端把文件加密成base64,后端接收并保存。
拿来主义,直接使用他们的代码是没有问题的,但根据自身框架及代码风格,需要把base64值封装成json传到后台。
改成json后,java后台报错:
java.lang.IllegalArgumentException: Illegal base64 character 25
at java.util.Base64$Decoder.decode0(Base64.java:714)
at java.util.Base64$Decoder.decode(Base64.java:526)
网上也没有相关问题,经过一番思考,发现是ajax传参问题。
demo前端代码:
// 确定按钮点击事件
$("#sureCut").on("click", function() {
if ($("#tailoringImg").attr("src") == null) {
return false;
} else {
var cas = $('#tailoringImg').cropper('getCroppedCanvas');// 获取被裁剪后的canvas
var base64 = cas.toDataURL('image/jpeg'); // 转换为base64
uploadFile(encodeURIComponent(base64))//编码后上传服务器
$("#finalImg").prop("src", base64);// 显示图片
closeTailor();// 关闭裁剪框
}
});
//ajax请求上传
function uploadFile(file) {
$.ajax({
url : '/demo/upload.do',
type : 'POST',
data : "file=" + file,
async : true,
success : function(data) {
console.log(data)
}
});
}
demo后端代码:
@RequestMapping(method = RequestMethod.POST)
@ResponseBody
public String cropper(@RequestParam("file") String file,
HttpServletRequest request) throws Exception {
Decoder decoder = Base64.getDecoder();
// 去掉base64编码的头部 如:"data:image/jpeg;base64," 如果不去,转换的图片不可以查看
file = file.substring(23);
//解码
byte[] imgByte = decoder.decode(file);
/**
*省略部分代码
**/
}
在前端demo里面,注意如下代码:
var base64 = cas.toDataURL('image/jpeg'); // 转换为base64
uploadFile(encodeURIComponent(base64))//编码后上传服务器
ajax的data参数:data : "file=" + file,
先把图片转成base64,再使用了encodeURIComponent进行编码,再传到后台,后台直接从file取base64字符串。
在把ajax换成json传参时,后台取到的base64字符串就不能解码了,报了错误:“java.lang.IllegalArgumentException: Illegal base64 character 25”
思考如下:
在demo里面传递参数时,使用的是“text/html;charset=utf-8”方式,这种请求在传递时,encodeURIComponent() 函数把字符串作为 URI 组件进行编码。@RequestParam可以从file里面取到值,这里的值是已经url解码过的(具体还没研究是哪里解码的)
我自己的前端代码:
// 确定按钮点击事件
$("#sureCut").on("click", function() {
if ($("#tailoringImg").attr("src") == null) {
return false;
} else {
var cas = $('#tailoringImg').cropper('getCroppedCanvas');// 获取被裁剪后的canvas
var base64 = cas.toDataURL('image/jpeg'); // 转换为base64
uploadFile(base64);
$("#finalImg").prop("src", base64);// 显示图片
closeTailor();// 关闭裁剪框
}
});
//ajax请求上传
function uploadFile(file) {
var data= {file : file};
$.ajax({
url : '/demo/upload.do',
type : "POST",
data : JSON.stringify(data),
dataType : "json",
async : false,
contentType : "application/json",
success : function(data) {
console.log(data)
}
});
}
后端代码:
@RequestMapping(value = "/ioUploadImage", method = {RequestMethod.POST, RequestMethod.GET})
@ResponseBody
public Map<String, Object> ioUploadImage(HttpServletRequest request, HttpServletResponse response,
RedirectAttributes redirectAttributes, @RequestBody Map<String,String> map) throws Exception {
String file = map.get("file");
/**省略部分代码**
}
把uploadFile(encodeURIComponent(base64))换成了uploadFile(base64),就可以直接使用json接收文件的base64值了。
下次有时间了,再研究下demo里面encodeURIComponent编码后为什么后台能直接取到解码后的值。