【n8n教程】:从零开始掌握表达式(Expressions),让数据流动起来!

在 n8n 中构建自动化工作流时,表达式(Expressions) 是连接各个节点、处理和转换数据的核心技能。许多初学者虽然已掌握 JSON 基础,但却不知道如何在节点之间传递和处理数据,导致工作流总是显得「死板」和「固定」。

本教程将带你深入 n8n 的灵魂——表达式系统,通过通俗易懂的讲解和实战案例,让你彻底告别静态工作流,解锁数据自动化的真正潜力。


什么是表达式?

表达式 是包含在 {{ }} 双花括号中的 JavaScript 代码片段。它们让你能够:

基础语法:


    
    
    
  {{ 你的 JavaScript 代码 }}

示例: 访问来自上一个节点的城市信息


    
    
    
  {{ $json.city }}

核心概念详解

1. 数据访问的基础

在 n8n 中,使用 $json 变量访问当前项目的 JSON 数据:

表达式说明用途
{{ $json }}获取整个 JSON 对象查看完整数据结构
{{ $json.fieldName }}获取特定字段提取单个数据值
{{ $json.address.city }}访问嵌套属性获取深层数据
{{ $itemIndex }}获取当前项目索引(从 0 开始)循环处理中定位位置

实际例子:

假设前一个节点返回了用户信息:


    
    
    
  {
  "name"
: "张三",
  "email"
: "zhangsan@example.com",
  "address"
: {
    "city"
: "北京",
    "zipcode"
: "100000"
  }

}

你可以这样访问:


    
    
    
  {{ $json.name }}                    // 返回: "张三"
{{ $json.address.city }}           // 返回: "北京"
{{ $json.email }}                  // 返回: "zhangsan@example.com"

2. 检查并验证输入数据

在实际工作中,数据并不总是完整的。你需要检查数据是否存在,以及是否符合预期。

使用三元运算符(Ternary Operator)

三元运算符是一种简洁的条件判断方式:


    
    
    
  {{ 条件 ? 为真时返回值 : 为假时返回值 }}

示例:检查变量是否为空


    
    
    
  {{ $json.phone !== undefined ? $json.phone : "未提供" }}

这个表达式的含义:

使用空值合并运算符(Nullish Coalescing Operator ??


    
    
    
  {{ $json.phone ?? "未提供" }}

这个运算符只在值为 nullundefined 时才使用默认值,对 0false 或空字符串保持原值。

使用逻辑 OR 运算符(||


    
    
    
  {{ $json.phone || "未提供" }}

注意:这个运算符会将 0false、空字符串等「假值」都替换为默认值。

对比三种方法:

方法当值为 null/undefined当值为 0/false/空字符串
三元运算符返回默认值返回原值
?? 空值合并返回默认值返回原值 ✓
|| 逻辑OR返回默认值返回默认值

常见问题与排查

❌ 问题 1:"不能获取表达式数据" (Can't get data for expression)

原因: 前置节点尚未执行,或者你引用的节点不存在。

解决方案:

  1. 1. 确保工作流已连接,前置节点会先执行
  2. 2. 检查节点名称是否正确
  3. 3. 可以用以下代码检查前置节点是否已执行:

    
    
    
  {{ $input.first() !== undefined ? $json.fieldName : "节点未执行" }}

❌ 问题 2:"无效的 JSON 输出" (The 'JSON Output' contains invalid JSON)

原因: 输出了格式不规范的 JSON,或引用了不存在的字段。

解决方案:

  1. 1. 使用 JSON 验证工具[1] 检查你的 JSON
  2. 2. 确保所有引用的字段实际存在于数据中
  3. 3. 示例:

    
    
    
  // ❌ 错误:引用不存在的字段
{{ $json.username.profile.notExistField }}

// ✓ 正确:先检查字段是否存在

{{ $json.username?.profile?.notExistField ?? "字段不存在" }}

❌ 问题 3:"语法错误" (Invalid syntax)

原因: 表达式代码有 JavaScript 语法错误。

解决方案:

  1. 1. 检查括号、引号是否成对
  2. 2. 检查是否有多余的逗号或句号
  3. 3. 在浏览器的开发者工具中测试 JavaScript 代码

高级技巧

1. 处理数组数据

当前置节点返回多个项目时,使用以下方法:

方法说明
{{ $input.first() }}获取第一项数据
{{ $input.last() }}获取最后一项数据
{{ $input.all() }}获取所有项目(返回数组)

示例:获取所有用户名称


    
    
    
  {{ $input.all().map(item => item.json.name).join(", ") }}

2. 字符串处理


    
    
    
  {{ $json.name.toUpperCase() }}              // 转换为大写
{{ $json.email.toLowerCase() }}            // 转换为小写
{{ $json.text.includes("关键词") }}        // 检查是否包含子串
{{ $json.name.substring(0, 3) }}           // 提取前 3 个字符

3. 数据验证与转换


    
    
    
  {{ typeof $json.age === 'number' ? $json.age : 0 }}           // 类型检查
{{ $json.enabled === true ? "启用" : "禁用" }}               // 布尔值判断
{{ Array.isArray($json.items) ? $json.items.length : 0 }}    // 数组长度检查

4. 日期/时间操作(使用 Luxon)


    
    
    
  {{ $now.toFormat("yyyy-MM-dd") }}          // 当前日期,格式化为 YYYY-MM-DD
{{ $today }}                                // 今天午夜时间
{{ $now.plus({days: 7}) }}                 // 当前时间加 7 天

实战案例:完整的数据验证工作流

现在我们构建一个真实场景的工作流:从 API 接收用户注册数据,验证数据完整性,然后根据验证结果执行不同的操作。

工作流设计

  1. 1. 数据源 (Webhook):接收用户注册请求
  2. 2. 数据检查 (Function):验证必填字段
  3. 3. 条件分支 (IF):根据验证结果分支处理
  4. 4. 成功路由:保存到数据库
  5. 5. 失败路由:返回错误信息

导入此工作流

将以下 JSON 代码复制到 n8n 中,选择 File > Import from URLFile > Import from Clipboard


    
    
    
  {
  "name"
: "数据验证与条件处理工作流",
  "description"
: "接收用户数据,验证完整性,根据结果执行不同操作",
  "nodes"
: [
    {

      "parameters"
: {},
      "id"
: "webhook-start",
      "name"
: "webhook",
      "type"
: "n8n-nodes-base.webhook",
      "typeVersion"
: 1,
      "position"
: [250, 300],
      "webhookId"
: "webhook-example"
    }
,
    {

      "parameters"
: {
        "jsCode"
: "// 验证用户数据的完整性\nconst data = $json;\nconst errors = [];\n\n// 检查必填字段\nif (!data.name || data.name.trim() === '') {\n  errors.push('姓名不能为空');\n}\n\nif (!data.email || !data.email.includes('@')) {\n  errors.push('请输入有效的电子邮件地址');\n}\n\nif (!data.phone) {\n  errors.push('电话号码不能为空');\n}\n\n// 检查年龄是否有效\nif (data.age && (data.age < 18 || data.age > 100)) {\n  errors.push('年龄必须在 18-100 之间');\n}\n\nreturn {\n  isValid: errors.length === 0,\n  errors: errors,\n  data: {\n    name: data.name?.trim() || '未提供',\n    email: data.email?.toLowerCase() || '未提供',\n    phone: data.phone || '未提供',\n    age: data.age ?? 0,\n    registrationTime: new Date().toISOString()\n  }\n};"
      }
,
      "id"
: "function-validate",
      "name"
: "数据验证",
      "type"
: "n8n-nodes-base.functionItem",
      "typeVersion"
: 1,
      "position"
: [450, 300]
    }
,
    {

      "parameters"
: {
        "conditions"
: {
          "boolean"
: [
            {

              "value1"
: "{{ $json.isValid }}",
              "value2"
: true,
              "operation"
: "equals"
            }

          ]

        }

      }
,
      "id"
: "if-validation",
      "name"
: "验证是否通过",
      "type"
: "n8n-nodes-base.if",
      "typeVersion"
: 1,
      "position"
: [650, 300]
    }
,
    {

      "parameters"
: {
        "content"
: "✅ 用户注册成功!\n\n姓名:{{ $json.data.name }}\n邮箱:{{ $json.data.email }}\n电话:{{ $json.data.phone }}\n年龄:{{ $json.data.age }}\n注册时间:{{ $json.data.registrationTime }}"
      }
,
      "id"
: "webhook-response-success",
      "name"
: "成功响应",
      "type"
: "n8n-nodes-base.webhookRespond",
      "typeVersion"
: 1,
      "position"
: [850, 150]
    }
,
    {

      "parameters"
: {
        "content"
: "❌ 用户注册失败!\n\n错误信息:\n{{ $json.errors.join('\\n') }}\n\n请检查以下信息并重试:\n- 姓名(必填)\n- 有效的电子邮件地址(必填)\n- 电话号码(必填)\n- 年龄 18-100 之间(可选)"
      }
,
      "id"
: "webhook-response-error",
      "name"
: "错误响应",
      "type"
: "n8n-nodes-base.webhookRespond",
      "typeVersion"
: 1,
      "position"
: [850, 450]
    }

  ]
,
  "connections"
: {
    "webhook-start"
: {
      "main"
: [
        [

          {

            "node"
: "function-validate",
            "type"
: "main",
            "index"
: 0
          }

        ]

      ]

    }
,
    "function-validate"
: {
      "main"
: [
        [

          {

            "node"
: "if-validation",
            "type"
: "main",
            "index"
: 0
          }

        ]

      ]

    }
,
    "if-validation"
: {
      "main"
: [
        [

          {

            "node"
: "webhook-response-success",
            "type"
: "main",
            "index"
: 0
          }

        ]
,
        [

          {

            "node"
: "webhook-response-error",
            "type"
: "main",
            "index"
: 0
          }

        ]

      ]

    }

  }

}

工作流说明

第 1 步:接收数据

第 2 步:验证数据


    
    
    
  // 在「数据验证」节点中使用 Function Item
const
 data = $json;
const
 errors = [];

// 逐一检查必填字段

if
 (!data.name || data.name.trim() === '') {
  errors.push('姓名不能为空');
}

// 返回验证结果

return
 {
  isValid
: errors.length === 0,
  errors
: errors,
  data
: { /* 清理后的数据 */ }
};

第 3 步:条件分支

第 4 步:返回结果

测试工作流

  1. 1. 部署工作流并获取 Webhook URL
  2. 2. 使用 curl 或 Postman 发送测试请求:

    
    
    
  # 有效数据(通过验证)
curl -X POST https://your-webhook-url \
  -H "Content-Type: application/json" \
  -d '{
    "name": "李四",
    "email": "lisi@example.com",
    "phone": "13800138000",
    "age": 28
  }'


# 无效数据(验证失败)

curl -X POST https://your-webhook-url \
  -H "Content-Type: application/json" \
  -d '{
    "name": "",
    "email": "invalid-email",
    "phone": ""
  }'

快速参考表

常用表达式

用途表达式
获取当前数据{{ $json }}
获取特定字段{{ $json.fieldName }}
条件判断{{ condition ? "是" : "否" }}
默认值(null/undefined){{ $json.field ?? "默认" }}
默认值(任何假值){{ $json.field || "默认" }}
检查非空{{ $json.field !== undefined ? $json.field : "未提供" }}
第一项数据{{ $input.first() }}
最后一项数据{{ $input.last() }}
所有项目{{ $input.all() }}
转大写{{ $json.text.toUpperCase() }}
转小写{{ $json.text.toLowerCase() }}
检查数组长度{{ Array.isArray($json.items) ? $json.items.length : 0 }}
当前时间戳{{ $now }}
格式化日期{{ $now.toFormat("yyyy-MM-dd") }}

总结

通过本教程,你已经掌握了:

✅ 表达式的基础概念和语法
✅ 如何访问和验证数据
✅ 使用三元运算符进行条件判断
✅ 空值合并与逻辑运算符的区别
✅ 常见错误的排查方法
✅ 一个完整的实战工作流案例


官方文档[2]
n8n系列教程[3]

引用链接

[1] JSON 验证工具: https://jsonlint.com/
[2] 官方文档: https://docs.n8n.io/code/cookbook/expressions/
[3] n8n系列教程: https://www.undsky.com/blog/?category=n8n%E6%95%99%E7%A8%8B#