变量与配置

在自动化系统中,灵活的配置能力是高效运维和安全保障的基础。本文系统介绍 n8n 的环境变量、内置变量与表达式,并重点说明 当一个节点有多个输入时如何正确获取与合并数据 的几种方式(包括官方推荐用法与 Code 节点示例)。

环境变量(自托管)

n8n 的大部分服务端行为可通过环境变量配置。典型变量如下:

变量作用常见取值/示例
N8N_DEFAULT_BINARY_DATA_MODE二进制数据存储模式default(内存 + 临时文件,默认)、filesystem
EXECUTIONS_DATA_PRUNE是否滚动清理历史执行数据true/false
EXECUTIONS_DATA_MAX_AGE执行数据最大保留时长(小时)例如 336(两周)。
EXECUTIONS_DATA_PRUNE_MAX_COUNT最多保留执行条数(0 表示不限制)10000
N8N_DEFAULT_LOCALEUI 默认语言(回退为 enende不支持区域化标识de-AT
GENERIC_TIMEZONE实例时区(影响定时等)Asia/Shanghai
N8N_BLOCK_ENV_ACCESS_IN_NODE是否禁止在表达式/Code 中访问 $envtrue/false。设为 true 会禁用 $env

注:n8n 1.0 起移除了面向 UI 的 Basic Auth/JWT 登录(改为用户管理/SSO 等)。若你曾使用 N8N_BASIC_AUTH_* 来保护编辑器登录,这是旧设定,现已不适用。请改用用户管理/SSO。

设置环境变量后需重启 n8n。

内置变量与表达式速查

n8n 在表达式与 Code 节点提供一组内置变量/方法:

  • 当前节点输入(最常用)
    • $json:等同 $input.item.json(在“逐条运行”模式下可用)。
    • $input.item / $input.all() / $input.first() / $input.last() / $input.params。这些 API 在 表达式和 Code 节点中都可用(Python 用 _input/_json 同名变体)。
  • 时间
    • $now$today:Luxon DateTime 对象,便于格式化/运算。
  • 其他节点输出(跨节点取数,支持表达式与 Code)
    • $('<节点名>').all() / .first() / .last() / .params
    • .itemMatching(i):在 Code 节点里,用来“顺着 item 链接(item linking)”找到与当前第 i 个输入对应的上游 item。
  • 环境变量$env.MY_ENV(若未被 N8N_BLOCK_ENV_ACCESS_IN_NODE 禁用)。

多输入节点:如何同时获取并合并数据?

核心事实(避免踩坑):

  1. 一个节点有多个输入时,n8n 通常会为每个输入分别执行一次(或按 item 链接执行)。此时:
    • $json$input.* 只代表“本次执行对应的那个输入”。
    • 表达式里没有 $input(1) 这种函数$input 是对象,不是函数。把 $input 当函数调用会得到你遇到的错误:$input is not a function。正确用法是 $input.all()$input.first() 等。
  2. 想要“在同一次执行中同时拿到多个上游的结果”,有两种官方认可方式: A. 先用 Merge 节点把两路数据合成一路B. 在表达式/Code 中直接用 $('<节点名>') 按名称取上游节点输出,必要时配合 .itemMatching(i) 精准配对。

方案 A:用 Merge 节点统一输入(推荐)

当你希望下游节点只处理一条合并后的 item 或者成对合并两路列表,使用 Merge 最省心。Merge 支持多种模式(Append、Combine/按字段、按位置、全组合、Choose Branch 等),常见的“按位置一一合并”在新版 UI 归入 Combine → Merge by Position

Merge 的行为与 item 链接关系密切。合并后如何保持/恢复链接,详见“Item linking”文档与示例。

方案 B:在表达式/Code 中按节点名取数据

无需额外 Merge,你可以在任意节点的表达式Code 节点直接取上游任意节点的输出:

  • 表达式示例: {{$("HTTP Request").first().json.result}} {{$("DB Query").last().json.rows}}$node["节点名"].json 仍可用,但 $() 系列在 1.x 对 item 链接支持更一致。

  • Code(JS)示例:

    const http = $('HTTP Request').first().json;
    const db   = $('DB Query').first().json;
    return [{ json: { ...http, ...db } }];
    

    $('…') 系列在 表达式与 Code 节点均可用。)

Code 节点:两个 JSON 同时合并的正确示例

模式选择:在 Code 节点的 Mode 里通常选择 Run Once(一次运行输出一个结果)或 Run Once for Each Item(逐条处理)。下面给出两种常见场景。

场景 1:两路各出一条,合并成一条(Run Once for All Item)

这段代码用于在 n8n 的 JavaScript Code 节点中,处理“Run Once for All Item”模式下的多路输入配对合并。

// Code 节点(JavaScript),Mode: Run Once for All Item

const a = $('输入 A').first().json;   // 读取名为“输入 A”的上游节点第一条
const b = $('输入 B').first().json;   // 读取名为“输入 B”的上游节点第一条

return [{ json: { ...a, ...b } }];

说明:该写法不依赖当前节点的多输入执行顺序,直接按名字取上游

场景 2:两路各出多条,按“位置”一一配对合并(Run Once for Each Item)

这段代码演示了在 JavaScript 的 Code 节点中,如何在“Run Once for Each Item”模式下,针对多路输入的每一条数据进行精准配对合并。通过 itemMatching(i) 方法,可以确保每个输出 item 都是由“输入 A”和“输入 B”中第 i 条数据一一对应合并而成。这种写法非常适用于需要保持输入数据顺序一致、逐条处理的场景,避免了因多分支或数据乱序导致的配对错误,从而提升了数据处理的准确性和可维护性。

// Code 节点(JavaScript),Mode: Run Once for Each Item
// 依赖 item 链接,使用 itemMatching(i) 精准找回与第 i 个输入配对的上游 item

const inputItems = $input.all(); // 当前输入的全部 items
const out = [];

for (let i = 0; i < inputItems.length; i++) {
  const a = $('输入 A').itemMatching(i).json; // 与当前第 i 条对应的“输入 A”上游 item
  const b = $('输入 B').itemMatching(i).json; // 与当前第 i 条对应的“输入 B”上游 item
  out.push({ json: { ...a, ...b } });
}

return out;

说明:.itemMatching(i)Code 节点专用的“沿 item 链接回溯”的方法,它能在多分支/合并之后,依然找回与当前第 i 条相匹配的上游 item。官方 cookbook 示例也用这种写法。

场景 3:如果你明确希望“先合后用”

在 Code 前放一个 Merge(Combine → Merge by Position/Fields),把两路合成一条/一组,再在 Code 里直接用 $json 即可:

// Merge → Code,Code 逐条模式
const a = $json.a;     // Merge 后统一结构中的 a
const b = $json.b;     // Merge 后统一结构中的 b
return [{ json: { ...a, ...b } }];

提示:当合并策略、冲突字段优先级或去重策略比较复杂时,Merge 节点更直观可靠。

常见表达式与函数

  • 读取字段:{{$json.id}} / {{$("Set").item.json.value}}
  • 三元判断:{{$json.name ? $json.name : "unknown"}}
  • 默认值:{{$json.x ?? "default"}}
  • 时间:{{$now.toISO()}}{{$today.toISODate()}}

数据转换函数(如 toDateTime()parseJson() 等)是表达式编辑器提供的“Data transformation functions”,不在 Code 节点内置。

常见错误与排查

  • TypeError: $input is not a function 原因:把 $input 当函数调用(如 $input(1))。 解决:$input对象,用 $input.all()$input.first()$input.item多上游请用 $("<节点>").… 或先 Merge。
  • 拿不到另一条输入的数据 说明:当前这次执行只关联其中一路输入。用 Merge 整合,或在表达式/Code 通过 节点名取数,并在 Code 中配合 .itemMatching(i)
  • 访问 $env 为空 检查是否设置了 N8N_BLOCK_ENV_ACCESS_IN_NODE=true

一图看懂

两条路径对比如下图所示:

两种方式对比
两种方式对比

说明:

  • 方案 A(Merge):Merge → 下游直接用 json 字段。
  • 方案 B(直接取数):在表达式/Code里按节点名读取:
    • 表达式里:示意 $("HTTP Request").first().json(不要把这串放进图里)。
    • Code 里多条配对:用 itemMatching 进行位置对应。

结论

下面总结了多输入节点数据获取与合并的常用方法和注意事项:

  • 单输入:直接用 $json / $input.*
  • 多输入
    • 想要一次性看到两路数据 → 先 Merge
    • 不想 Merge 或需精准配对 → 在 表达式/Code 中用 $('<节点>'),并在 Code 中用 .itemMatching(i)
  • 不要写 $input(1)$input 不是函数。

文章导航

独立页面

这是书籍中的独立页面。

书籍首页

评论区