假设我正在使用Node/Express创建一个REST API,客户端和服务器之间通过JSON交换数据。
用户正在填写注册表单,其中一个字段是图像输入,用于上传个人资料图片。无法通过JSON发送图像,因此必须将其转换为base64字符串。
如何在服务器端验证这确实是图像的base64字符串?或者最好不要将个人资料图片作为base64发送?
假设我正在使用Node/Express创建一个REST API,客户端和服务器之间通过JSON交换数据。
用户正在填写注册表单,其中一个字段是图像输入,用于上传个人资料图片。无法通过JSON发送图像,因此必须将其转换为base64字符串。
如何在服务器端验证这确实是图像的base64字符串?或者最好不要将个人资料图片作为base64发送?
const isBase64 = require('is-base64');
let base64str_img = 'data:image/jpeg;base64,/9j/4AAQSkZJRgABAQEASABIAAD/2wBDAAoHBwgHBgoIC...ljA5GC68sN8AoXT/AF7fw7//2Q==';
console.log(isBase64(base64str_img, { mime: true })); // true
您可以验证 MIME 类型是否在您的应用程序中允许,或进行其他验证,例如尝试显示图像文件并捕获可能的错误。
无论如何,如果您想确保用户输入的真实性,首先您需要自己处理它。这就是您应该关注的最佳实践。
只有当Base64值的解码数据具有正确的MIME类型,并且宽度和高度大于零时,它才是有效的图像。一种方便的检查方法是安装 jimp 包并按照以下方式使用:
var b64 = 'R0lGODdhAQADAPABAP////8AACwAAAAAAQADAAACAgxQADs=',
buf = Buffer.from(b64, 'base64');
require('jimp').read(buf).then(function (img) {
if (img.bitmap.width > 0 && img.bitmap.height > 0) {
console.log('Valid image');
} else {
console.log('Invalid image');
}
}).catch (function (err) {
console.log(err);
});
我想做类似的事情,于是上网搜索却一无所获,最终我自己编写了一个 base64 验证器:
function isBase64(text) {
let utf8 = Buffer.from(text).toString("utf8");
return !(/[^\x00-\x7f]/.test(utf8));
}
这并不是很好,因为我将它用于不同的目的,但你可能可以在此基础上进行构建,以下是一个使用 atob
的示例,以防止无效的 base64 字符(否则它们将被忽略):
function isBase64(text) {
try {
let utf8 = atob(text);
return !(/[^\x00-\x7f]/.test(utf8));
} catch (_) {
return false;
}
}
Buffer.from(text, "base64")
会从字符串中删除所有无效的 base64 字符,然后将字符串转换为缓冲区,toString("utf8")
将缓冲区转换为字符串。atob
做了类似的事情,但是当它遇到无效字符时会抛出错误(因此使用 try...catch
)。
!(/[^\x00-\x7f]/.test(utf8))
如果解码后的字符串中的所有字符都属于 ASCII 字符集,则返回 true
,否则返回 false
。可以将其更改为使用较小的字符集,例如,[^\x30-\x39\x41-\x5a\x61-\x7a]
只有当所有字符都是字母数字时才会返回 true
。