Node.js运行generateSignature函数报trim is not a function错误,无法解决
签名函数触发
TypeError: data[key].trim is not a function的排查与修复 报错根因
trim()是JavaScript字符串原型上的专有方法,只有字符串类型的值可以正常调用。该报错的核心触发逻辑是:函数循环读取入参data的属性值时,直接默认所有属性值都是字符串类型,没有做任何类型校验,一旦碰到数字、布尔值、null、undefined、嵌套对象这类非字符串类型的值,就会因为找不到trim方法直接抛出异常。
结合现有代码的判断逻辑,存在两个明显的校验漏洞:
- 原有空值判断
if (data[key] !== "")无法拦截非字符串类型的值:比如数字0、布尔值false、null这类值都不等于空字符串,会直接跳过判断进入.trim()的调用分支 - 没有对值的实际类型做前置判断,完全依赖调用方传入的data参数全为字符串格式
修复方案
在参数处理逻辑中补全类型判断与强制转换,避免非字符串值直接触发方法调用,改造后的稳定版本函数如下:
const generateSignature = (data, passPhrase = null) => { // 拼接待签名的参数字符串 let pfOutput = ""; for (let key in data) { if (data.hasOwnProperty(key)) { const rawValue = data[key]; // 跳过null、undefined类无效值 if (rawValue === null || rawValue === undefined) continue; // 非字符串类型强制转为字符串后再执行trim操作 const strValue = String(rawValue).trim(); // 过滤掉转换后为空的参数 if (strValue === "") continue; pfOutput += `${key}=${encodeURIComponent(strValue).replace(/%20/g, "+")}&`; } } // 移除拼接后末尾多余的&符号 const getString = pfOutput.slice(0, -1); // 追加密码短语参数 if (passPhrase !== null) { getString += `&passphrase=${encodeURIComponent(String(passPhrase).trim()).replace(/%20/g, "+")}`; } return crypto.createHash("md5").update(getString).digest("hex"); };
快速定位异常入参的调试技巧
如果改造后仍偶发同类报错,可以在参数循环逻辑中加入临时调试日志,快速定位是哪个调用方传入了格式异常的参数:
for (let key in data) { if (data.hasOwnProperty(key) && typeof data[key] !== 'string') { console.log(`格式异常参数:键名${key},值为${data[key]},值类型为${typeof data[key]}`) } }
额外提示:原代码中将
%20替换为带前后空格的" + "的逻辑存在格式风险,会导致签名串和服务端的计算规则不一致,建议统一替换为无空格的"+",避免出现签名校验不通过的问题。
内容的提问来源于stack exchange,提问作者Gerald Muller
相关产品推荐
相关产品推荐

