上文写到使用html2Canvas实现截屏。上次留了一个问题,如果当前dom元素对象比较大,比如包含一个比较大的图片等,在将dom序列化成字符串时,极易导致字符串超长。对于超长的内容,后台程序将获取不到参数,那么怎么解决这个问题呢?
基本实现思路有三种:
1、对dom里的元素瘦身,减少序列化后的参数值长度。
存在问题:对于无法再瘦身的dom怎么办?怎么体现通用性(一段代码解决大多数场景)?
2、修改web中间件的上传大小限制。
存在问题:对web中间件依赖增强,如果需要跨中间件则非常麻烦,通用性太低。
3、采用文件上传的思路绕过传统form参数限制。
优点:只需要修改表单提交方式,完全实现分离,支持所有平台。
缺点:需要前后台支持文件的读写与转换,不过这个成本几乎可以忽略不计。
具体实现
一、瘦身伪码,思路就是尽量最小化需要序列化的dom元素。
('helpPage').= 'none';//设置隐藏
('helpPage').remove();//删除元素
二、设置服务中间件参数限制,以tomcat为例。
tomcat7.0.63之前的版本
maxPostSize 设置为 0 或者负数
Connector 节点中加入maxPostSize="0" 或者 maxPostSize="-1"
tomcat7.0.63之后的版本,需要设置为负数
Connector 节点中加入 maxPostSize="-1"
在tomcat文件夹下的conf文件中的 配置中添加:
maxPostSize="-1" //-1 表示不限制大小
maxPostSize:指定POST方式请求的最大量,没有指定默认为2097152。
三、前端序列化成file,使用文件上传的方式提交后台。
前台基本代码如下:
function saveAsImageData(){
var userTemplateId = ;
var pic,dataUrl ;
var canvas2 = ("canvas"); //创建一个新的canvas
let _canvas = ('#main'); //这里面填写 你需要截图的div
var w = parseInt((_canvas).width);
var h = parseInt((_canvas).height);
= w;
= h;//将canvas画布放大2倍或者更多,然后盛放在较小的容器内,就显得不模糊了
= w + "px";
= h + "px";
var context = ("2d");
(1, 1); //指图片偏移
html2canvas(('#main'), { //写需要截图的div
taintTest: false,useCORS: true,allowTaint: false, //这三串代码解决跨域问题
canvas: canvas2
}).then(
function (canvas) {
dataUrl = ("image/png");
var arr = (',')
var mime = arr[0].match(/:(.*?);/)[1]
var suffix = ('/')[1]
var bstr = atob(arr[1])
var n =
var u8arr = new Uint8Array(n)
while (n--) {
u8arr[n] = (n)
}
var file = new File([u8arr], `temp_img.${suffix}`, {type: mime});
var formdata = new FormData();
("file",file)
$.ajax({
url: url,//路径
type: "POST",
data: formdata,
contentType: false,
multiple: true,
processData: false,
success: function (data) {
},
error: function (error) {
}
});
});
}
后台代码如下:
@RequestMapping("fileUpload2")
public String fileUpload2(@RequestParam("file") CommonsMultipartFile file) throws IOException {
long startTime=();
("fileName:"+());
String path="E:/"+new Date().getTime()+();
File newFile=new File(path);
(newFile);
return "/success";
}
本文阐述了在使用html2Canvas时,遇到序列化字符太大无法完成提交的问题的解决方案。分析了各个方案的适用场景和具体实现思路。当然可能还有更好的实现方式,欢迎交流讨论。