1. 场景描述
在前后端进行表单提交业务中, 有图片之类的附件上传是一个非常常见的场景。
也会遇到同一张表单需要重复修改提交的操作, 例如做一张报销审核单, 那么提交上去的单据可能别审核的人员打回,然后需要重新进行提交。 这时候附件就会有一个问题。
假如第一次提交上去的附件是 A,B 。 重复提交的附件还是A,B , 后台要怎么处理这种情况呢 ?
我们知道,一个附件,在数据库中的存储,就是一条记录。 第一次提交产生了两条记录 a, b .
那么,在第二次提交了相同的两张照片,数据库是新增两条数据吗? 显然,我们希望数据库中改单据对应的附件列表,始终是不重复的,一来方便数据操作, 而来减少数据库的开销。 就图片而言,如果只是保存一个图床的url映射倒是没有什么影响,但是如果是base64 , 如果不经过压缩,那么存储过程,以及占用空间都是一个很大的问题。
2. 工作中遇到的一种解决方案
图片查验的方式有很多种。 这里提一种我最近工作种遇到的方式。
我们给每张图片包装为一个对象,含有一个id值,当我提交的时候,这个值为空, 到服务器后,给定给图片一个id值。 第二次提交,之前我肯定需要先获取到我之前上传的照片, 这是返回时,就携带了id值。 所以当我再次提交时, 如果是之前已经发送过的图片,那么,就有id值,后台就不会重新新增重复的数据, 而如果是新的照片,id值就是空的。后台就会新增。
2.1 具体的模拟数据:
第一次提交: 客户端 --> 服务端
[
{
file_name:"this is pic 1"
image_base64_datastr:'xxxxxx_very_long_xxxxxxx',
id:''
},
{
file_name:"this is pic 2"
image_base64_datastr:'xxxxxx_very_long_xxxxxxx',
id:''
}
]
客户端获取历史提交数据:
[
{
file_name:"this is pic 1"
image_base64_datastr:'xxxxxx_very_long_xxxxxxx',
id:'aksbjansdj;oisjd8qwu84fu2h3'//打上id以标记
},
{
file_name:"this is pic 2"
image_base64_datastr:'xxxxxx_very_long_xxxxxxx',
id:'odnlasfoai90389ji23nr89hd32'//打上id以标记
}
]
第二次提交: 客户端 --> 服务端
[
{
file_name:"this is pic 1"
image_base64_datastr:'xxxxxx_very_long_xxxxxxx',
id:'aksbjansdj;oisjd8qwu84fu2h3'//打上id以标记
},
{
file_name:"this is pic 2"
image_base64_datastr:'xxxxxx_very_long_xxxxxxx',
id:'odnlasfoai90389ji23nr89hd32'//打上id以标记
},
{
file_name:"this is pic 3"
image_base64_datastr:'xxxxxx_very_long_xxxxxxx',
id:''//新增照片
}
]
可以看到,客户端会将所有首次发过去的照片的id字段填充, 然后在客户端再次获取历史单据时返回已经填充的id, 这样,当再次提交时, 新的图片的id就是空的,而已有的图片就是有id值的。
2.2 原理图示
特别注意,这种方式,仅仅是通过判断,图片是不是新增。 意味着,就算你新增的照片是重复的,后台也会认为这是两张照片。 即
发送:
[ { file_name:"this is pic 4" image_base64_datastr:'xxxxxx_very_long_xxxxxxx', id:''//新增照片 } ]
获取:
[ { file_name:"this is pic 4" image_base64_datastr:'xxxxxx_very_long_xxxxxxx', id:'dnaolnfadsfhdfjas9233426sdf'//新增照片 } ]
再次发送:
[ { file_name:"this is pic 4" image_base64_datastr:'xxxxxx_very_long_xxxxxxx', id:'dnaolnfadsfhdfjas9233426sdf'//被标记 }, { file_name:"this is pic 4" image_base64_datastr:'xxxxxx_very_long_xxxxxxx', id:''//新增照片 }, ]
此时,即便两张照片是同样的,但是服务端也会认为是两张。
3. 一点想法
所以,其实,想这种去重操作往往是有多个环节,和不同手段的。
例如前端,去重,直接不允许你添加重复照片。
再比如后端去重。
去重的手段也很多,基本的文件名判断,文件字节大小判断,exif信息判断, 等等。
本文只是在遇到这种解决方式时,觉得有一些巧妙。所以记录下来。