公司需求html5手写签名,并转换成图片上传服务器
链接: jSignature官方插件下载地址,下载后解压找到lib文件导入到自己项目中去并引用即可.
项目结构:jquery+springboot项目需要引入js文件:jquery的jquery.min.js 、jSignature插件的 jSignature.min.js 、flashcanvas.js文件 小白注意:引入js的方式我是通过thymeleaf,不是该模板的请通过绝对路径或者相对路径等其他方式引入,其中ajax中的url路径已置空,自行添加。
关于为何不直接通过base64传输图片?公司xss拦截代码会拦截关键字,直接传输base64会被拦截,所有最终选择使用ajax传输流文件上传图片
**
效果图如下
**
前端HTML5部分代码
<!DOCTYPE html>
<html xmlns:th="http://www.w3.org/1999/xhtml">
<meta charset="utf-8">
<meta name="context-path" th:content="@{/}"/>
<style type="text/css">
a{text-decoration:none;}
a:hover{ text-decoration:none;}
#box{
width: 100%;
height: 400px;
border: 1px solid #eaeaea;
}
canvas{
height: 400px !important;
}
.abspan{
color: #ffffff;
display: block;
width: 100px;
font-size: 16px;
text-align: center;
line-height: 40px;
background: dodgerblue;
margin-bottom: 10px;
}
</style>
<body>
<div style="margin: 12px;">
<div class="form-group">
<label class="col-sm-3 control-label">本人姓名确认</label>
<div class="col-sm-8">
<div id="box">
</div>
<span class="abspan" id="su">确认</span>
<span class="abspan" id="re">重置</span>
<img src="" alt="" id="image">
</div>
</div>
<div class="form-group">
<div class="col-sm-8 col-sm-offset-3">
<a id="save" class="btn btn-primary" οnclick="javascript:save()">提交</a>    
</div>
</div>
</form>
</div>
<script type="text/javascript"th:src="@{/js/jquery.min.js}"></script>
<script type="text/javascript"th:src="@{/js/jSignature.min.js}"></script>
<script type="text/javascript"th:src="@{/js/flashcanvas.js}"></script>
<script>
$(function() {
$("#box").jSignature();//初始化画板,初始化之后就可以进行操作
});
function save() {
//先将图片保存到服务器,在把其他表单数据提交到服务器(具体如何关联取决业务)
saveImage();
saveForm();
}
//点击事件为获取base64数据,生成图片
document.getElementById("su").onclick = function(){
//getData:获取数据
//reset:复位/重置
// 获取签名的“base64”数据对
var datapair = $("#box").jSignature("getData","image");
//此处打印的是完整的base64转码,可以复制后去在线转码测试一下是否正常
console.log('data:' + datapair[0] + "," + datapair[1])
//将图片展示出来
$("#image").attr('src','data:' + datapair[0] + "," + datapair[1]);
}
//生成图片之后我们就可以进行相应的操作
//点击事件为重置画板
document.getElementById("re").onclick = function(){
$("#box").jSignature("reset");
$("#image").attr('src','');
}
var url='';//设置你们的url
//保存整个表单在此之前已经将图片上传到服务器了
function saveForm(){
$.ajax({
cache : true,
type : "POST",
url : url,
data : $('#form').serialize(), // 你的formid
async : false,
error : function(request) {
alert("网络超时");
},
success : function(data) {
console.log(data)
}
});
}
//重点来了,该方法将Base64格式转换成流格式
function base64toFile(dataurl, filename) {
let arr = dataurl.split(',')
let mime = arr[0].match(/:(.*?);/)[1]
let suffix = mime.split('/')[1]
let bstr = atob(arr[1])
let n = bstr.length
let u8arr = new Uint8Array(n)
while (n--) {
u8arr[n] = bstr.charCodeAt(n)
}
return new File([u8arr], `${filename}.${suffix}`, {
type: mime
})
}
function saveImage() {
var url='';//设置你们的url
var datapair = $("#box").jSignature("getData","image"); //将canvas里面的数据转换成base64数组
var imgBase64='data:' + datapair[0] + "," + datapair[1]; //封装成正确的base64
var file= base64toFile(imgBase64,'file'); //base64转换成流文件,可以打印出来看下
let formData = new FormData() //封装成formData格式
formData.append('type', 97);
formData.append('file', file)
$.ajax({
contentType: false, //不可少
processData: false, //不可少
type : "POST",
url : url,
data : formData,
async : false,
error : function(request) {
alert("网络超时");
},
success : function(data) {
console.log(data)
}
});
}
</script>
</body>
</html>
后端接收数据部分代码
//上传文件并通过流的方式接收,我的业务做法是将文件上传后拿到文件id及地址存储到数据库,
//拿到流文件后如何上传具体可以参考别的文章
@PostMapping("/upLoadItemImage")
@ResponseBody
public String upLoadItemImage(HttpServletRequest request, Integer type) {
MultipartHttpServletRequest fileRequest = (MultipartHttpServletRequest) request;
Map<String, MultipartFile> fileMap = fileRequest.getFileMap();
for (Map.Entry<String, MultipartFile> entity : fileMap.entrySet()) {
MultipartFile file = entity.getValue();
int id = 0;
try {
InputStream inputStream = file.getInputStream();
//自行操作
//...
} catch (Exception e) {
e.printStackTrace();
}
if(id == 0){
return "error" ;
}
}
return "ok";
}