【n8n教程】:Respond to Webhook 节点,打造专属 API 端点!

想象一个场景:你需要为你的业务创建一个 API 端点来接收来自其他应用的数据并返回自定义响应,但又不想写一行代码。这时候,n8n 的 Respond to Webhook 节点就成为了你的秘密武器!

这个节点允许你完全控制 webhook 响应,是构建专业级 API 的关键。今天的教程将帮助你从零开始,理解它的每个细节。


🎯 核心概念:什么是 Respond to Webhook 节点?

Respond to Webhook 节点是一个响应控制器,它与 Webhook 节点搭配使用,能让你自定义返回给外部系统的 HTTP 响应。

为什么你需要它?

需求场景传统方式使用 Respond to Webhook
创建 API 端点需要编写后端代码拖拽节点,可视化配置
自定义响应内容修改代码、重新部署实时调整参数
返回不同的状态码需要条件判断代码在节点中直接配置
处理多种数据格式需要格式化逻辑内置 JSON、Text、Binary 等选项

🔧 快速上手:三步搭建你的第一个 API

第一步:创建 Webhook 触发节点

  1. 1. 打开 n8n,点击 "+ Add first step"
  2. 2. 搜索并添加 Webhook 节点
  3. 3. 配置关键参数:
    • HTTP Method:选择 POST(最常用)
    • Path:填写 /api/greeting(这是你的 API 路由)
    • Respond:选择 "Using 'Respond to Webhook' node" ⚠️ 这一步很重要!

第二步:添加业务逻辑(可选)

在 Webhook 和 Respond to Webhook 之间添加 Set 节点来处理数据:


    
    
    
  {
  "message"
: "Hello {{ $json.body.name || 'Guest' }}",
  "timestamp"
: new Date().toISOString()
}

第三步:配置响应节点

  1. 1. 添加 Respond to Webhook 节点
  2. 2. 配置响应内容:
    • Respond With:选择 JSON
    • Response Body{{ $json }}
    • Response Code200

完成!你的 API 已经准备就绪。


🎨 Respond to Webhook 节点的 7 种响应方式

这个节点提供了多种响应选项,满足不同场景的需求:

1️⃣ All Incoming Items - 返回所有输入项

适用于需要返回数组数据的场景。

配置示例:


    
    
    
  Respond With: All Incoming Items
Response Code: 200

API 响应:


    
    
    
  [
  {
 "id": 1, "name": "Item A" },
  {
 "id": 2, "name": "Item B" }
]

2️⃣ First Incoming Item - 只返回第一项

当你的工作流处理多条数据,但只需返回其中一条时使用。

3️⃣ JSON - 自定义 JSON 响应

最灵活的选项,可以构建任意 JSON 结构。

配置示例:


    
    
    
  {
  "status"
: "success",
  "data"
: {{ JSON.stringify($json.result) }},
  "timestamp"
: "{{ new Date().toISOString() }}"
}

4️⃣ Text - 纯文本响应

可返回纯文本或 HTML 内容(默认 Content-Type: text/html)。

配置示例:


    
    
    
  <html>
  <body>

    <h1>
请求已收到,处理中...</h1>
  </body>

</html>

5️⃣ Binary File - 返回二进制文件

用于下载 PDF、图片、文档等文件。

6️⃣ Redirect - HTTP 重定向

将用户重定向到其他 URL。

配置示例:


    
    
    
  Response Code: 302
Redirect URL: https://example.com/thank-you

7️⃣ No Data - 空响应

仅返回状态码,适合异步处理的场景。

配置示例:


    
    
    
  Respond With: No Data
Response Code: 202 (Accepted)

⚙️ 进阶配置:Node Options

除了基本的响应类型,你还可以配置更多选项:

📌 Response Code(响应状态码)

状态码含义使用场景
200OK成功响应
201Created成功创建资源
202Accepted请求已接受,后续处理
400Bad Request请求参数错误
403Forbidden无权限访问
404Not Found资源不存在
500Server Error服务器错误

📌 Response Headers(响应头)

可以添加自定义 HTTP 头来控制客户端行为:


    
    
    
  // 示例:添加 CORS 头
Name
: Access-Control-Allow-Origin
Value
: *

// 示例:缓存控制

Name
: Cache-Control
Value
: no-cache

📌 Put Response in Field(字段映射)

当使用"All Incoming Items"或"First Incoming Item"时,可以将响应放在特定字段下,而不是直接返回:


    
    
    
  // 配置此字段为 "result",响应将被包装为:
{
  "result"
: [{ /* 实际数据 */ }]
}

📌 Enable Streaming(启用流式传输)

用于 AI 代理和实时数据流场景,允许数据边处理边返回。


🚨 常见错误及解决方案

❌ 错误 1:工作流执行但没有响应

原因: Webhook 节点的 Respond 设置为 "Immediately" 而不是 "Using Respond to Webhook node"

解决方案:


    
    
    
  打开 Webhook 节点 → Respond 选项 → 选择 "Using 'Respond to Webhook' node"

❌ 错误 2:"Invalid JSON in Response Body"

原因: 你传入了 JavaScript 对象而不是字符串化的 JSON

错误示例:


    
    
    
  // ❌ 错误
{{ $json.data }}

// ✅ 正确

{{ JSON.stringify($json.data) }}

❌ 错误 3:无法看到实际返回的响应

原因: 默认情况下,Respond to Webhook 节点的输出面板只显示输入数据

解决方案:
打开 Respond to Webhook 节点 → Settings 标签 → 启用 "Enable Response Output Branch"

这会生成第二个输出分支,显示实际发送的响应。

❌ 错误 4:响应状态码始终是 200

原因: 没有在 Response Code 字段中设置自定义状态码

解决方案:
点击 "Add Option" 按钮 → 勾选 "Response Code" → 输入需要的状态码


💡 实战案例:构建一个数据处理 API

让我们创建一个实际应用场景:接收用户数据,进行验证,返回结果

工作流架构


    
    
    
  Webhook (接收) 
    ↓
Set 节点 (准备数据)
    ↓
If 节点 (验证逻辑)
    ├→ Respond to Webhook (成功响应)
    └→ Respond to Webhook (错误响应)

完整工作流代码

将以下 JSON 导入到 n8n(菜单 → Import from File/Clipboard):


    
    
    
  {
  "name"
: "用户数据处理 API",
  "nodes"
: [
    {

      "parameters"
: {
        "path"
: "api/validate-user",
        "httpMethod"
: "POST",
        "responseMode"
: "responseNode"
      }
,
      "id"
: "webhook-trigger",
      "name"
: "Webhook",
      "type"
: "n8n-nodes-base.webhook",
      "typeVersion"
: 2,
      "position"
: [250, 300]
    }
,
    {

      "parameters"
: {
        "assignments"
: [
          {

            "name"
: "email",
            "value"
: "={{ $json.body.email }}"
          }
,
          {

            "name"
: "name",
            "value"
: "={{ $json.body.name }}"
          }

        ]

      }
,
      "id"
: "set-data",
      "name"
: "Set",
      "type"
: "n8n-nodes-base.set",
      "typeVersion"
: 3.3,
      "position"
: [500, 300]
    }
,
    {

      "parameters"
: {
        "conditions"
: {
          "options"
: {
            "caseSensitive"
: true,
            "leftValue"
: "={{ $json.email }}",
            "operator"
: {
              "name"
: "filter.operator.regex",
              "type"
: "string",
              "singleValue"
: true
            }
,
            "rightValue"
: "^[^\\s@]+@[^\\s@]+\\.[^\\s@]+$"
          }

        }

      }
,
      "id"
: "if-validate",
      "name"
: "If",
      "type"
: "n8n-nodes-base.if",
      "typeVersion"
: 2,
      "position"
: [750, 300]
    }
,
    {

      "parameters"
: {
        "respondWith"
: "json",
        "responseBody"
: "{\n  \"status\": \"success\",\n  \"message\": \"用户数据验证通过\",\n  \"data\": {\n    \"email\": \"{{ $json.email }}\",\n    \"name\": \"{{ $json.name }}\",\n    \"verified_at\": \"{{ new Date().toISOString() }}\"\n  }\n}",
        "responseCode"
: 200
      }
,
      "id"
: "respond-success",
      "name"
: "Respond Success",
      "type"
: "n8n-nodes-base.respondToWebhook",
      "typeVersion"
: 1.2,
      "position"
: [1000, 200]
    }
,
    {

      "parameters"
: {
        "respondWith"
: "json",
        "responseBody"
: "{\n  \"status\": \"error\",\n  \"message\": \"邮箱格式不正确\",\n  \"error_code\": \"INVALID_EMAIL\"\n}",
        "responseCode"
: 400
      }
,
      "id"
: "respond-error",
      "name"
: "Respond Error",
      "type"
: "n8n-nodes-base.respondToWebhook",
      "typeVersion"
: 1.2,
      "position"
: [1000, 400]
    }

  ]
,
  "connections"
: {
    "webhook-trigger"
: {
      "main"
: [[{ "node": "set-data", "type": "main", "index": 0 }]]
    }
,
    "set-data"
: {
      "main"
: [[{ "node": "if-validate", "type": "main", "index": 0 }]]
    }
,
    "if-validate"
: {
      "main"
: [
        [
{ "node": "respond-success", "type": "main", "index": 0 }],
        [
{ "node": "respond-error", "type": "main", "index": 0 }]
      ]

    }

  }
,
  "active"
: false,
  "settings"
: {}
}

使用这个 API

激活工作流后,你会获得类似这样的 URL:


    
    
    
  https://your-n8n-instance.com/webhook/api/validate-user

测试请求(使用 cURL):


    
    
    
  # ✅ 有效的邮箱
curl -X POST 'https://your-n8n-instance.com/webhook/api/validate-user' \
  -H 'Content-Type: application/json' \
  -d '{
    "email": "user@example.com",
    "name": "张三"
  }'


# 响应:

# {

#   "status": "success",

#   "message": "用户数据验证通过",

#   "data": {

#     "email": "user@example.com",

#     "name": "张三",

#     "verified_at": "2024-12-02T14:30:00.000Z"

#   }

# }


# ❌ 无效的邮箱

curl -X POST 'https://your-n8n-instance.com/webhook/api/validate-user' \
  -H 'Content-Type: application/json' \
  -d '{
    "email": "invalid-email",
    "name": "李四"
  }'


# 响应:

# {

#   "status": "error",

#   "message": "邮箱格式不正确",

#   "error_code": "INVALID_EMAIL"

# }

🔐 安全性最佳实践

1. 添加身份验证

在 Webhook 节点中启用认证,选择:

2. 验证输入数据


    
    
    
  // 在 Set 节点或 Code 节点中验证
if
 (!$json.body.email || !$json.body.name) {
  throw
 new Error('Missing required fields');
}

3. 设置正确的 Response Headers


    
    
    
  Name: X-Content-Type-Options
Value: nosniff

Name: X-Frame-Options
Value: DENY

Name: Content-Security-Policy
Value: default-src 'none'

📊 工作流行为总结

情况行为
工作流完成但没有 Respond to Webhook 节点返回默认 200 状态码
工作流在 Respond to Webhook 之前出错返回 500 错误
有两个 Respond to Webhook 节点执行只有第一个被执行
在没有 webhook 的情况下执行 Respond to Webhook节点被忽略

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

引用链接

[1] 官方文档: https://docs.n8n.io/integrations/builtin/core-nodes/n8n-nodes-base.respondtowebhook/
[2] n8n系列教程: https://www.undsky.com/blog/?category=n8n%E6%95%99%E7%A8%8B#