避坑落井第一期

本文最后更新于:9 个月前

20230823-2

避坑落井第一期

新增一个专题,记录日常踩坑笔记,基本上都是自己挖坑自己跳 [泪] !

需求简介

功能其实很简单,从前端获取到用户上传的图片,将图片转换为base64格式,再传递给后端进行处理。

代码实现

首先要获取用户上传的图片,在前端JavaScript中,由于安全性和隐私性考虑,不能直接获取用户上传图片的路径。但是,可以通过某些方法处理用户上传的图片。

例如,可以使用HTML的<input type="file">元素来让用户选择要上传的图片。然后,在JavaScript中,可以通过该元素的files属性获取用户选择的文件列表。然后,可以使用FileReader API来读取这些文件。

eg:

1
<input type="file" id="imageUpload">
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
document.getElementById('imageUpload').addEventListener('change', function(event) {  
var file = event.target.files[0];
var reader = new FileReader();

reader.onloadend = function() {
// reader.result包含了图片的Data URL,也就是base64格式的字符串
console.log(reader.result);
};

if (file) {
reader.readAsDataURL(file);
} else {
console.log('没有选择文件');
}
});

在这个示例中,当用户选择了一个图片文件后,JavaScript会读取这个文件,并把它的内容以Data URL的形式输出到控制台。Data URL是一种直接在网页上展示图片的方法,它包含了图片的所有数据。

需要注意的是,虽然这个方法可以获取到图片的数据,但是它并不能获取到图片的路径。因为出于安全考虑,现代浏览器不允许JavaScript获取用户本地文件系统的路径。

那么我想用户上传图片后,可以让用户预览自己上传的图片:

1
2
3
4
5
6
7
reader.onloadend = () => {
const base64String = reader.result;
console.log(base64String);
const imgElement = document.createElement('img');
imgElement.src = base64String;
document.getElementById('incomeImgBase64').appendChild(imgElement);
};

首先获取到reader对象的result属性,即base64字符串。然后创建一个新的img元素,将src属性设置为base64字符串。最后,将img元素添加到id为’incomeImgBase64’的元素中。这样,就可以在网页上看到base64编码的图片了。

这步搞定,就应该把base64字符串传递给后端进行处理了,在这一步,不知道我什么时候写了一行代码:

1
let img = encodeURIComponent(base64String);

我把刚刚转好的base64字符串又做了一遍处理,导致给到后端华为云ocr识别接口时报错:

1
2
3
4
5
6
ClientRequestException {
httpStatusCode: 400
errorCode: AIS.0102
errorMsg: The image format is not supported.
requestId: 7ea4cb308b32de0b37ad7d2f3b34a6ed
}

这行代码是将一个Base64字符串编码为URI组件(Uniform Resource Identifier)。

encodeURIComponent是JavaScript内置的函数,用于将URI组件中的特殊字符进行编码,使其可以作为URL的一部分使用。

在上述过程中,img变量被赋值为encodeURIComponent函数对base64String变量进行编码后的结果。这意味着img变量现在包含了一个经过编码的Base64字符串,可以作为URL的一部分,例如在HTML中的图像URL中。

这行代码注释掉以后完美解决。

踩坑小结

一开始就在想,它后端报这个错肯定是图片有问题,那就先排查后端有没有接收到前端传过来的base64字符串,断点排查以后是有的,接收到了;

那么我在后端写一个测试类,通过图片路径来获取到该图片的base64字符串,再走ocr识别接口,发现可以成功的;

那我能不能前端获取图片路径呢?答案是不能,因为出于安全考虑,现代浏览器不允许JavaScript获取用户本地文件系统的路径。

那这样的话我猜就是前端获取到用户上传的图片后,转base64字符串出的问题,那么我把前端转的base64字符串打印出来,拷贝到华为云接口控制台测试,发现是成功的;那这就奇怪了,再往后看调用后端接口的方法,发现了问题所在。

总之,每日踩踩坑,坑坑都不同!


避坑落井第一期
http://example.com/2023/08/23/避坑落井第一期/
作者
crush
发布于
2023年8月23日
更新于
2023年9月6日
许可协议