关于安卓和ios图片上传问题(base64、bolb、file)
1、安卓获取图片的问题 base64开头为data:img
安卓获取的base64格式图片中含有"\n"字符,其中\n字符会导致base64转bolb文件失败,具体表现为window.atob(base64),报参数错误,错误信息:ailed to execute ‘atob’ on ‘window’: the string to be decoded is not correctly encoded.
至于安卓为何有\n:RFC2045中有规定,The encoded output stream must be represented in lines of no more than 76 characters each(Base64一行不能超过76字符,超过则添加回车换行符)。
2、IOS获取图片信息的问题
IOS获取图片会有空格符号,也会导致上诉问题
3、安卓和IOS获取的base64图片数据的头部不相同
安卓的base64图片信息为:“data:img/;base64”,IOS获取的base64图片信息的头部为:data:image/ ;base64
4、前端具体代码(框架:vue,请求:axios)
//第一步获取base64
let base64 = '';
//处理base64数据存在的异常
base64 = base64.replace(/[\s*\t\n\r]/g,'');
//通过FormData传输file
let formData = new FormData();
let type = base64.split('/')[1].split(';')[0];
let fileName = 'dddd.'+type;
//当blob返回值为false时,说明图片解析失败,终止axios请求
let blob = dataURLtoBlob(base64);
formData.append("file",blobToFile(blob),fileName);
//将base64转换为blob
//AXIOS数据请求,请求头需新增:Content-Type: multipart/form-data;
this.$http{
type: 'post',
url: '',
data: formData,
header: {
Content-Type: 'multipart/form-data';
Authorization: TOKEN
}
}
.then(res=>{
})
.catch(err=>{
console.log(err);
})
//base64转化为blob对象
function dataURLtoBlob(dataurl) {
let arr,mime,bstr,n,u8arr;
try {
arr = dataurl.split(','),
mime = arr[0].match(/:(.*?);/)[1],
bstr = atob(arr[1]),
n = bstr.length,
u8arr = new Uint8Array(n);
while (n--) {
u8arr[n] = bstr.charCodeAt(n);
}
} catch (error) {
//部分获取的图片只有一部分数据,在atob解析时会出错,可能拍照时部分数据丢失
alert('图片解析异常,请重新拍照上传!');
return false;
}
return new Blob([u8arr], { type: mime });
}
//将blob转换为file
function blobToFile(theBlob, fileName){
theBlob.lastModifiedDate = new Date();
theBlob.name = 'dddd.jpg';
return theBlob;
}
5、直接传输base64到后端处理问题
问题: 传输过程中特殊字符(比如:+)被替换成空格
解决方法:将base64字符串通过encode编码,encodeURIComponent(str),传输到后端后通过decode解码
后端读取base64只显示部分问题
public static String GetImageStrFromUrl(String imgURL) {
byte[] data = null;
try {
URL url = new URL(imgURL);
HttpURLConnection conn = (HttpURLConnection)url.openConnection();
conn.setRequestMethod("GET");
conn.setConnectTimeout(5 * 1000);
InputStream inStream = conn.getInputStream();
ByteArrayOutputStream outStream = new ByteArrayOutputStream();
byte[] buffer = new byte[1024];
//每次读取的字符串长度,如果为-1,代表全部读取完毕
int len = 0;
while ((len = inStream.read(buffer)) != -1) {
outStream.write(buffer, 0, len);
}
inStream.close();
data = outStream.toByteArray();
} catch (IOException e) {
e.printStackTrace();
}
String base64Image = Base64.getEncoder().encodeToString(data);
return base64Image;
}