n8n 里的数据到底长什么样:别再看着 JSON 发愣

上一篇我们知道了节点像一条工作流上的不同岗位。这一篇不增加任何复杂节点,只做一件更重要的事:看懂岗位之间究竟传了什么。

你可能已经把两个节点连起来过。

第一个节点执行成功,变成绿色;第二个节点也能打开。可一旦你想把“上一节点的姓名”填进“下一节点的消息”,就开始不知道该点哪里。右侧突然出现一大段 JSON;里面有花括号、方括号、字段名、值。你看到 name、body、headers,却不知道哪个才是自己要用的内容。

于是你开始靠猜:试着写一个字段名,运行失败;再换一种写法,还是空白;最后只能把示例里的固定文字复制进去。工作流看起来跑通了,但它并没有真的读懂自己的数据。

这不是你不会拖节点。问题在于:你还没有把 n8n 里的数据,看成会在岗位之间传递的资料卡。

一句话结论: n8n 的每个节点都会接收一张或多张资料卡,处理后再交出新的资料卡。JSON 不是一堵代码墙,它只是资料卡上“字段名:内容”的写法。

今天我们不接 Webhook,不连 API,也不需要任何账号。我们只用一条最小工作流,亲手写一张资料卡、看它如何传递,再把卡片里的两个字段拼成一句真正会变化的话。


先看你最终会得到什么

完成后,你的画布上只有三步:

Manual Trigger
      ↓
写入一张资料卡(Edit Fields / Set)
      ↓
把资料卡写成一句话(Edit Fields / Set)

第一次运行后,你会亲眼看到下面这条变化:

{
  "name": "小林",
  "task": "看懂 n8n 里的数据"
}

变成:

{
  "message": "你好,小林,今天要完成:看懂 n8n 里的数据"
}

这不是为了生成一句问候。它是在练习后续所有自动化都会用到的基本动作:上一步产生数据,下一步读取数据,再把数据变成新的结果。

最小工作流:手动触发、写入资料、生成消息

先把 JSON 想成一张资料卡

假设你在前台收到一张纸质申请单。上面写着“姓名:小林”“今天要做:看懂 n8n 里的数据”。这张纸交到下一个岗位时,对方不需要猜第一行是什么、第二行是什么;因为每个内容都有固定的栏目名。

JSON 只是把这张资料卡写成机器更容易传递的样子:左边是栏目名,右边是栏目里的内容。

{
  "name": "小林",
  "task": "看懂 n8n 里的数据"
}

这里不需要背语法。你只要先看懂两件事:name 是栏目名,小林 是这个栏目里的内容;task 是另一个栏目名,右边则是它的内容。

你在 n8n 里看到的东西 用资料卡理解 它真正表示什么
字段(field) 资料卡上的一个栏目。 例如 name、task、message。
值(value) 栏目里实际填写的内容。 例如“小林”或“看懂 n8n 里的数据”。
JSON 按“栏目名:内容”写好的资料卡。 节点之间传递的结构化数据格式。
item 一张完整资料卡。 n8n 处理数据的基本单位。
输入(INPUT) 当前岗位刚收到的资料卡。 来自上游节点的输出。
输出(OUTPUT) 当前岗位处理后交出去的资料卡。 将传给下游节点的数据。

n8n 官方将节点间传递的数据描述为对象数组:一条资料卡是一个 item,多条资料卡会组成一组;当节点接收到多条 item 时,通常会逐条处理它们。1

为什么我在界面里经常看不到 json 这层?

从底层结构看,n8n 会把普通数据放进 item 的 json 键中。概念上,它更接近下面这样:

[
  {
    "json": {
      "name": "小林",
      "task": "看懂 n8n 里的数据"
    }
  }
]

不过,在编辑器的输入与输出面板里,n8n 通常会优先把你真正关心的 json 内容展开显示。因此你看到的往往只是:

{
  "name": "小林",
  "task": "看懂 n8n 里的数据"
}

这不是数据少了一层,而是界面替你把资料卡的外封套先收起来了。现在先把注意力放在字段和值上即可。


开始前,你只需要确认一件事

请先确认你能打开自己的 n8n,并能新建一个空白工作流。如果你还没有可用环境,可以先完成本站的本地部署或 VPS 部署文章;本篇不重复安装和 Docker 配置。4

本篇示例全部使用假数据。不要在练习字段中填写真实密码、API Key、身份证号或客户信息。一次 execution 就是工作流的一次运行,执行记录会保存运行相关信息;n8n 提供执行数据脱敏能力,但最稳妥的入门习惯仍然是:测试时只用测试资料。3


第 1 步:用 Manual Trigger 放下第一张空白资料卡

新建一个工作流,点击画布中的 Add first step,选择 Manual Trigger。

Manual Trigger 的作用并不是“产生重要数据”,而是给你一个可以随时按下的启动按钮。此时你还没有连接外部表单、定时任务或 Webhook;你只是告诉 n8n:现在开始跑一次练习流程。

点击节点右侧或工作流顶部的 Execute Workflow。运行成功后,Manual Trigger 会显示绿色勾选。

这一步在做什么? 它让整条接力线开始一次手动运行。你可以把它理解为前台按下“开始处理”的按钮。

成功标志: Manual Trigger 变为绿色;点击该节点时,右侧或底部的数据面板不会出现报错。此时它交给下一步的是一张还没有写入业务内容的资料卡。

如果和教程不同: 有些版本会把执行入口显示在节点面板内,有些版本显示在画布上方。只要你最终看到本次运行成功,并且节点状态变绿,就说明第一步已完成。

第 1 步:用 Manual Trigger 启动一次手动练习

第 2 步:用 Edit Fields 写入一张真正的资料卡

在 Manual Trigger 后添加 Edit Fields (Set) 节点。为了以后回看不迷路,把节点重命名为:

写入一张资料卡

在节点中新增两个文本字段。界面中的按钮可能显示为 Add Field、Add Field to Set 或相近名称;核心是创建字段名与字段值。

字段名 类型 值
name String / 文本 小林
task String / 文本 看懂 n8n 里的数据

然后点击执行当前节点,或再次点击 Execute Workflow。

执行后,选中“写入一张资料卡”节点,打开它的 OUTPUT。你应当看到接近下面的内容:

{
  "name": "小林",
  "task": "看懂 n8n 里的数据"
}

这一步在做什么? Edit Fields (Set) 像资料录入岗。它把两项信息写进一张结构清楚的资料卡,供后面的节点读取。n8n 官方也建议:如果主要目的就是增加、修改、删除或重命名字段,可以先用 Edit Fields (Set) 准备干净的数据,再将结果交给后续节点,而不是把复杂处理分散到每个节点参数里。2

成功标志: 你能在 OUTPUT 中看见 name 和 task 两个字段,右边的值与自己填写的一致。

非常重要: 这时请不要只看节点是否变绿。绿色只说明节点执行没有报错;真正的验证是打开 OUTPUT,看它实际交出了什么资料卡。以后工作流出现“能运行但内容不对”时,这就是第一处要看的位置。

第 2 步:Edit Fields 将 name 与 task 写进一张资料卡

第 3 步:区分 INPUT 与 OUTPUT,找到资料卡是在哪里变化的

现在仍停留在“写入一张资料卡”节点。打开数据面板中的 INPUT 与 OUTPUT,并来回切换一次。

你会发现:INPUT 里没有刚才写入的 name 和 task;OUTPUT 里才出现这两个字段。

这正是 n8n 最重要的一条观察习惯:

INPUT 是这个节点收到什么;OUTPUT 是这个节点处理后交出了什么。
你正在看哪个区域 应该问自己什么 本例中应看到什么
INPUT 这张资料卡从上一岗位带来了什么? 没有业务字段,或只有触发器带来的基础数据。
OUTPUT 当前岗位对资料卡做了什么? 新增了 name 与 task。
下一节点的 INPUT 下一岗位实际收到了什么? 应与“写入一张资料卡”的 OUTPUT 对应。

不要急着背 $json、$input 或节点选择器。只要每次先做这件事——在当前节点先看 INPUT,再看 OUTPUT——你就能知道数据到底是在上一步没来,还是在这一步被改掉了。

第 3 步:对比 INPUT 收到什么与 OUTPUT 交出什么

第 4 步:让下一节点读取资料卡,而不是重新手打内容

再添加一个 Edit Fields (Set) 节点,连接在“写入一张资料卡”之后。将它重命名为:

把资料卡写成一句话

在这个节点中新建一个文本字段:

字段名 值的写法
message 你好,{{ $json.name }},今天要完成:{{ $json.task }}

填写这个值时,请把该字段切换到 Expression 模式。更稳妥的做法不是手敲字段名,而是先在本节点的 INPUT 区域找到 name 和 task,将它们分别拖入表达式编辑区,再在中间补上固定文字。n8n 的拖放数据映射会创建类似 {{ $json.name }} 的字段路径表达式。1

如果你的编辑器要求整个字段都处在表达式模式,也可以写成:

{{ '你好,' + $json.name + ',今天要完成:' + $json.task }}

再次执行工作流,然后打开“把资料卡写成一句话”的 OUTPUT。你应当看到:

{
  "message": "你好,小林,今天要完成:看懂 n8n 里的数据"
}

这一步在做什么? 上一个节点负责写资料卡;当前节点负责从卡片中读出两个栏目,再生成一项新的内容。$json.name 的意思是“读取当前输入资料卡中的 name 字段”,$json.task 同理。

成功标志: message 中不再出现字面量 {{ $json.name }},而是显示真实的“小林”;同时句子中的任务内容来自上一节点,而不是你在本节点重新输入的一段固定文字。

如果和教程不同: 如果你只看到 你好,{{ $json.name }} 这样的原始文字,通常是字段仍在固定文本模式,没有切换为 Expression;如果显示空白或 undefined,先不要改表达式,回到本节点 INPUT 确认是否真的存在名为 name 的字段。

第 4 步:从上一步的 name 与 task 字段自动生成动态消息

最关键的一次验证:故意改一张资料卡,看下游会不会跟着变化

真正理解数据,不是只让一次示例跑通,而是确认下游节点真的在读取上游结果。

回到“写入一张资料卡”节点,把两个值改为:

字段名 新值
name 阿澄
task 整理本周阅读清单

再次执行整条工作流。然后按下面顺序检查:

  1. 打开“写入一张资料卡”的 OUTPUT,确认资料卡已经变成 阿澄 与 整理本周阅读清单。
  2. 打开“把资料卡写成一句话”的 INPUT,确认它收到了同样的字段。
  3. 打开最后一个节点的 OUTPUT,确认 message 自动变成:
你好,阿澄,今天要完成:整理本周阅读清单

如果三处都正确,你就完成了本篇最重要的验证:你不是在让节点各做各的,而是在让数据沿着连线真正传递。

最关键验证:改动上游资料卡后,下游消息自动跟着变化

现在你该怎样看一段 JSON?

以后你打开一个 Webhook、HTTP Request、Notion 或 RSS 节点时,可能看到的资料卡会比本篇复杂得多。例如:

{
  "title": "今天的文章",
  "author": {
    "name": "小林",
    "city": "杭州"
  },
  "tags": ["n8n", "自动化"]
}

不要试图第一眼读完所有内容。按下面顺序看即可。

看到的数据形状 先怎么理解 后续要怎样引用
"title": "今天的文章" 一项直接写在资料卡上的内容。 {{ $json.title }}
"author": { ... } author 里面还有一张小资料卡。 先展开它,再找内部字段。
"name": "小林" 位于 author 内 这是嵌套资料中的姓名。 {{ $json.author.name }}
"tags": [ ... ] 一个栏目里装着一组内容。 下一篇“多条数据与数组”会专门讲。

嵌套数据并不表示它更高级,只表示资料卡里有一个栏目下面还放了几项子信息。n8n 官方文档也以 nested 字段演示了这种层级数据;编辑器会把可展开的嵌套内容显示出来。1

现在先记住一个最实用的办法:不要猜路径。先在节点 INPUT 里展开字段,确认它的层级,再把需要的值拖到表达式里。

看到嵌套 JSON 时,按直接字段、内部资料卡和一组内容的顺序阅读

跟教程不同怎么办:先按这个顺序排查

你看到的情况 不要急着做什么 应该先做什么
节点是绿色的,但 OUTPUT 没有 name 或 task 不要先改下游表达式。 回到“写入一张资料卡”,确认字段名、字段类型和保存后的 OUTPUT。
message 显示 undefined 或空白 不要立刻把字段写死为固定文字。 打开“把资料卡写成一句话”的 INPUT,确认字段是否存在、拼写是否完全相同。
message 原样显示 {{ $json.name }} 不要怀疑上游数据已经丢失。 确认当前字段处于 Expression 模式,而不是普通固定文本模式。
INPUT 面板没有任何数据 不要先删除节点重建。 先执行整条工作流,或至少执行当前节点之前的节点;前置节点未运行时,表达式无法读取它的结果。2
改了上游内容,最后结果还是旧值 不要只点击最后一个节点反复执行。 从 Manual Trigger 重新执行整条流程,再按节点顺序检查最新的 INPUT 与 OUTPUT。
数据面板里出现真实密码、Token 或客户资料 不要截图发到公开群或直接分享执行记录。 立即停止使用真实数据做演示;检查执行数据保存与脱敏设置,并改用测试资料。3

你现在真正看懂了什么

今天没有连接任何复杂服务,但你已经掌握了以后每条 n8n 工作流都要反复使用的四个判断:

每次搭流程前都可以问的问题 你现在的判断方法
这张资料卡从哪里来? 看当前节点的 INPUT;它来自上游节点的 OUTPUT。
当前节点做了什么? 对比 INPUT 与 OUTPUT,找到新增、修改或删除的字段。
下一节点要拿哪一项? 在 INPUT 中找到字段路径,用拖放创建表达式。
为什么最后内容不对? 从最后一个异常节点往回看 INPUT 与 OUTPUT,而不是先重做整条流程。
资料卡从哪里来,决定你能读什么;资料卡变成什么,决定下一步能做什么。

只要这条线清楚,JSON 就不再是让人发愣的代码。它只是你的工作流在不同岗位之间交接资料时,使用的一种清楚写法。


下一篇预告

下一篇我们专门解决一个更具体的问题:你已经能在 INPUT 里看到 name、title 和链接了,但怎样让下一个节点自动把它们填进通知、Notion 页面或 API 请求?

我们会把今天出现过的 {{ $json.name }} 拆开讲清楚,完成第一条真正可复用的动态内容流程:

n8n 的表达式怎么写:让下一个节点自动拿到上一节点的数据。

参考资料

[1]n8n Docs:Understand n8n's data structure

[2] n8n Docs:Expressions for data transformation

[3] n8n Docs:Understand executions

[4] QiLinora:如何使用 Windows 部署本地 n8n