API 返回的 JSON 乱成一锅粥?是时候让 Code 节点出手了
在做 n8n 自动化时,最让人头疼的往往不是发请求本身,而是请求回来的数据。API 返回的 JSON 结构复杂,嵌套层级深,字段命名不规范,直接用这些数据去填 Excel、写数据库或发通知,简直是场灾难。
笔者见过太多同学在 n8n 里疯狂堆砌 Set 节点和复杂表达式,试图把数据“掰直”。其实,n8n 里有一个神器——Code 节点,它能让你用最熟悉的 JavaScript 逻辑,把脏数据清洗得明明白白。
今天,N8N大学 就带你实战演练,用 Code 节点把杂乱的 API 响应,变成干净、结构化的数据流。
实战场景:处理复杂的电商订单数据
假设我们调用了一个电商 API,获取订单详情。返回的数据结构如下,嵌套深、字段名不友好:
{
"order_id": "20231001001",
"customer": {
"info": {
"full_name": "张三",
"contact": {
"mobile": "13800138000"
}
}
},
"items": [
{ "sku": "A001", "qty": 2, "price": 100 },
{ "sku": "B002", "qty": 1, "price": 50 }
],
"status": 1
}
我们的目标是清洗成这样,方便后续写入 Google Sheets:
{
"订单号": "20231001001",
"客户姓名": "张三",
"手机号": "13800138000",
"商品列表": "A001(2件), B002(1件)",
"总金额": 250,
"状态": "已付款"
}
核心实操:Code 节点清洗三步走
第一步:准备数据与节点配置
在 n8n 工作流中,HTTP Request 节点获取数据后,直接连接一个 Code 节点。
点击 Code 节点,确保 Language 选择 JavaScript。在下方的 Code 框中,我们可以访问上一个节点传递过来的数据。n8n 会将数据封装在 items 数组中,通常我们取第一个元素:const rawData = items[0].json;。
第二步:提取与扁平化数据
这是最基础的操作。我们需要从深层嵌套中提取值,并重命名字段。
const rawData = items[0].json;
// 提取深层数据
const orderId = rawData.order_id;
const customerName = rawData.customer.info.full_name;
const phone = rawData.customer.info.contact.mobile;
// 构造新对象
const cleanData = {
"订单号": orderId,
"客户姓名": customerName,
"手机号": phone
};
// 必须返回数组格式,n8n 才能继续流转
return [{ json: cleanData }];
避坑提示: Code 节点的输出必须是数组格式,且每个元素是一个对象,结构为 { json: { ...你的数据... } }。直接返回对象会报错。
第三步:处理数组与复杂逻辑
对于订单中的商品列表(items),我们需要遍历数组,拼接字符串,并计算总价。
const rawData = items[0].json;
// 计算商品描述字符串
// map 用于转换每个商品项,join 用于拼接
const itemsDesc = rawData.items.map(item => {
return `${item.sku}(${item.qty}件)`;
}).join(', ');
// 计算总金额
const totalAmount = rawData.items.reduce((sum, item) => {
return sum + (item.price * item.qty);
}, 0);
// 状态映射
const statusMap = { 1: '已付款', 2: '已发货', 3: '已完成' };
const statusText = statusMap[rawData.status] || '未知状态';
const cleanData = {
"订单号": rawData.order_id,
"客户姓名": rawData.customer.info.full_name,
"手机号": rawData.customer.info.contact.mobile,
"商品列表": itemsDesc,
"总金额": totalAmount,
"状态": statusText
};
return [{ json: cleanData }];
这里我们用到了 map 和 reduce 这两个 JS 数组方法,它们是处理批量数据的利器,比在表达式里写循环要高效得多。
进阶技巧:容错与数据类型转换
实战中,API 返回的数据往往不可靠。比如字段可能缺失,或者数字被返回成了字符串(如 "100")。
处理空值与默认值
在 JS 中,我们可以使用短路运算符(||)或可选链操作符(?.)来避免程序因读取不到字段而崩溃。
const phone = rawData.customer?.info?.contact?.mobile || '无手机号';
// 如果层级太深报错,加上 ?. 安全访问,如果结果是 null/undefined,使用默认值
强制类型转换
虽然 JS 是弱类型语言,但为了数据一致性,最好显式转换。
// 将字符串数字转为真正的数字
const price = Number(rawData.items[0].price);
// 将日期字符串转为标准格式
const date = new Date(rawData.created_at).toISOString();
避坑指南:Code 节点常见报错
在 N8N大学 的社区里,关于 Code 节点的提问通常集中在以下两点:
- ReferenceError: items is not defined:
这是因为你没有正确获取输入数据。在 Code 节点中,输入数据默认存储在items变量中。如果你开启了“为每一项执行”,则需要遍历 items 数组处理。 - 输出格式错误:
再次强调,输出必须是[{ json: {...} }]。如果你直接写return {...},下一个节点将无法读取数据。 - 性能问题:
如果输入数据量巨大(例如几千条),在 Code 节点中进行复杂的循环或正则替换会阻塞执行。此时应考虑使用“为每一项执行”模式,让 n8n 并行处理。
FAQ 问答
Q1: Code 节点和 Set 节点有什么区别?
Set 节点适合做简单的字段重命名、添加固定值或简单的数学运算(如 a+b)。但一旦涉及数组遍历、条件判断(if/else)、正则匹配或复杂的字符串拼接,Set 节点的表达式会变得非常臃肿且难以维护。这时,请毫不犹豫地使用 Code 节点。
Q2: 我不懂 JavaScript,能用好 Code 节点吗?
Code 节点其实就是写 JS 代码。如果你完全不懂编程,建议先学习 JS 的基础语法(变量、对象、数组方法)。对于简单的转换,你可以参考 N8N大学 的现成代码片段库。对于复杂的逻辑,掌握 JS 是必须的技能。
Q3: Code 节点处理后的数据,如何传给后续节点?
只要按照规范返回 [{ json: data }] 格式,后续节点(如 Google Sheets、HTTP Request)就能直接读取。你可以通过点击节点查看“Output”来验证数据结构是否正确。
总结与资源
Code 节点是 n8n 自动化流程中的“瑞士军刀”。它赋予了你处理任意数据结构的能力,打破了 API 与数据库/应用之间的数据格式壁垒。
掌握它,你的工作流将从“勉强能跑”进化到“稳定优雅”。建议大家多练习 JS 的数组方法(map, filter, reduce),这是数据清洗的核心内功。
更多 n8n 实战技巧,请持续关注 N8N大学 (n8ndx.com)。