空输入框表单(FormData)提交后变为”null”字符串

Yukino 912 2021-12-29

记录一次bug排查

一、场景

一个空的输入框在保存之后并无异常,再次编辑空白保存之后,其中的内容变为了null。

二、排查过程

找到这个”null”是什么时候产生的,所以先查看了get到的数据,显示是desc: null,这是没问题的,表单显示也是正常的,没有任何内容,但当再次点击保存时,再获取到的文本就变为了”null”,查看保存的post表单内容desc: "null",这就奇怪了,但这也定位了问题——前端处理。
接下来要找到这个null是在哪里变成”null”的,我在表单提交前一步打印了表单对象,里面的内容仍旧是null,突然注意到提交前一步还有将form对象的内容append到params中,看了一下params是一个FormData(FormData() - Web API 接口参考 | MDN)对象,那是不是在append的过程中变成了”null”呢。
最后找到FormData.append()(FormData.append() - Web API 接口参考 | MDN)方法,我找到了直接原因:

formData.append(name, value);
formData.append(name, value, filename);

1. name
	value中包含的数据对应的表单名称。
2. value
	表单的值。可以是USVString 或 Blob (包括子类型,如 File)。
3. filename 可选
	传给服务器的文件名称 (一个 USVString), 当一个 Blob 或 File 被作为第二个参数的时候, Blob 对象的默认文件名是 "blob"。 File 对象的默认文件名是该文件的名称。

value时只接收String和Blob,也就是字符串和二进制文件,而JS是弱语言,所以在传入时调用了Object.toString(),把null转化成了“null”(可以用这段代码检验console.log(new String(null)))。
这一部分的最后我们来还原“案发现场”:

let formData = new FormData();
formData.append('a', null);
for(var pair of formData.entries()) {
   console.log(typeof pair[1]);
}

// string

三、 解决问题

知道了问题是如何产生的也就好解决了,在append之前对null进行检验,将其替换为“”空字符串即可。


# 前端 # JS