第 8 期:与世界通信 — HTTP Request 节点的认证、轮询与并发

⏱ 预计阅读 14 分钟 更新于 2026/4/9

HTTP Request 是 n8n 的瑞士军刀

当 n8n 没有提供某个服务的专用节点(如没有"微信公众号节点")时,HTTP Request 是你的万能备选。它能手动调用任何 REST API。

graph LR
    subgraph "n8n HTTP Request 能力矩阵"
        HR[HTTP Request 节点]
        HR --> M1[GET / POST / PUT / DELETE]
        HR --> M2[Headers / Body / Query Params]
        HR --> M3[OAuth2 / API Key / Bearer Token]
        HR --> M4[分页 Pagination]
        HR --> M5[超时与重试]
        HR --> M6[响应格式: JSON/XML/Binary]
    end
    
    style HR fill:#ff6d5b,stroke:#e55a4e,color:#fff

1. 认证方式全解

API Key 认证

// ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
// 方式 1: API Key 放在 Header 中 (最常见)
// ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
{
  "method": "GET",
  "url": "https://api.example.com/data",
  "authentication": "genericCredentialType",
  "genericAuthType": "httpHeaderAuth",
  // 在 n8n Credentials 中配置:
  // Name: "Authorization"
  // Value: "Bearer sk-xxxxxxxxxxxxxxxx"
}

// ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
// 方式 2: API Key 放在 Query 参数中
// ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
{
  "method": "GET",
  "url": "https://api.openweathermap.org/data/2.5/weather",
  "queryParameters": {
    "q": "Shanghai",
    "appid": "={{ $credentials.openWeatherApiKey }}"  // 从凭证安全引用
  }
}

OAuth2 认证

sequenceDiagram
    participant N8N as 🤖 n8n
    participant Auth as 🔐 OAuth Server
    participant API as 🌐 API Server
    
    Note over N8N: 首次连接时
    N8N->>Auth: 1. 重定向用户到授权页面
    Auth-->>N8N: 2. 用户授权,返回 Authorization Code
    N8N->>Auth: 3. 用 Code 换取 Access Token + Refresh Token
    Auth-->>N8N: 4. 返回 Token (有效期通常 1 小时)
    
    Note over N8N: 后续请求
    N8N->>API: 5. 携带 Access Token 调用 API
    API-->>N8N: 6. 返回数据
    
    Note over N8N: Token 过期时
    N8N->>Auth: 7. 用 Refresh Token 自动刷新 (n8n 自动处理!)
    Auth-->>N8N: 8. 返回新的 Access Token
// ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
// OAuth2 凭证配置要点 (以 Google Sheets 为例)
// ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

// 在 n8n Credentials 中创建 "OAuth2 API" 凭证:
// - Authorization URL: https://accounts.google.com/o/oauth2/auth
// - Access Token URL:  https://oauth2.googleapis.com/token
// - Client ID:         从 Google Cloud Console 获取
// - Client Secret:     从 Google Cloud Console 获取
// - Scope:             https://www.googleapis.com/auth/spreadsheets
// 
// ⚠️ n8n 会自动管理 Token 刷新,你不需要写任何续期代码!

2. POST 请求与 Body 传递

// ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
// POST JSON Body 示例: 向 Slack Webhook 发送消息
// ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
{
  "method": "POST",
  "url": "https://hooks.slack.com/services/T.../B.../xxx",
  "sendBody": true,
  "bodyParameters": {
    "contentType": "json",          // 告诉 n8n 以 JSON 格式发送
    "jsonOutput": {                 // 可直接写 JSON 或用表达式
      "text": "={{ '新订单: ' + $json.orderId + ' | 金额: ¥' + $json.amount }}",
      "channel": "#orders"
    }
  },
  "options": {
    "timeout": 5000,                // 5 秒超时
    "redirect": {
      "followRedirects": true       // 自动跟随 3xx 重定向
    }
  }
}

3. 分页遍历 (Pagination)

大多数 API 不会一次返回所有数据,而是分页返回。n8n 内置了自动分页功能:

graph TB
    subgraph "自动分页流程"
        Start[发起第 1 页请求] --> Check{还有下一页?}
        Check -->|"有: next_cursor 存在"| Next[请求下一页]
        Next --> Merge[合并本页 Items]
        Merge --> Check
        Check -->|"无: 最后一页"| Done[输出全部 Items]
    end
    
    style Check fill:#f59e0b,stroke:#d97706
// ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
// 配置自动分页 (Offset-based 模式)
// ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
{
  "method": "GET",
  "url": "https://api.example.com/users",
  "queryParameters": {
    "limit": 100,                   // 每页 100 条
    "offset": "={{ $pageCount * 100 }}"  // n8n 自动递增 $pageCount
  },
  "options": {
    "pagination": {
      "paginationMode": "off",      // "off" | "updateAParameterInEachRequest"
      // 当设为 updateAParameterInEachRequest:
      // - Parameter: "offset"       // 每次递增的参数名
      // - Expression: "={{ $pageCount * 100 }}"
      // - Max Pages: 50             // 安全阀: 最多请求 50 页防止无限循环
      //
      // 停止条件 (Complete Expression):
      // {{ $response.body.length === 0 }}   // 返回空数组时停止
    }
  }
}

// ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
// Cursor-based 分页 (现代 API 更常用)
// ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
{
  "url": "https://api.example.com/users",
  "queryParameters": {
    "cursor": "={{ $response.body.next_cursor || '' }}"  // 首次为空,后续用上一页的 cursor
  }
  // 停止条件: {{ !$response.body.next_cursor }}
}

4. 错误处理与重试

// ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
// HTTP Request 错误处理配置
// ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
{
  "options": {
    // 🛡️ 错误策略: 默认情况下,非 2xx 响应会导致工作流停止
    // 设置 "Never Error" 让非 2xx 也作为正常输出
    "response": {
      "neverError": true           // 4xx/5xx 不中断,交给下游 If 判断
    },
    
    // ⏱️ 超时控制
    "timeout": 30000,              // 30 秒超时 (默认是无限等待!)
    
    // 🔄 自动重试 (处理瞬时网络故障)
    "retry": {
      "maxTries": 3,               // 最多重试 3 次
      "waitBetweenTries": 1000     // 每次重试间隔 1 秒
    }
  }
}
graph TB
    HTTP[HTTP Request] --> Check{响应状态码}
    Check -->|"200 OK"| Success[✅ 正常处理]
    Check -->|"429 Rate Limit"| Wait[⏳ Wait 节点: 等待 60 秒] --> HTTP
    Check -->|"500 Server Error"| Retry{重试次数 < 3?}
    Retry -->|"是"| HTTP
    Retry -->|"否"| Alert[🚨 发送告警]
    Check -->|"404 Not Found"| NotFound[记录日志: 资源不存在]
    
    style Check fill:#f59e0b,stroke:#d97706

5. 实战:批量爬取 GitHub Stars

// ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
// 场景: 获取某个 GitHub 仓库的所有 Stargazer 用户列表
// GitHub API 每页最多 100 条,需要分页处理
// ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
{
  "method": "GET",
  "url": "https://api.github.com/repos/n8n-io/n8n/stargazers",
  "authentication": "genericCredentialType",
  "genericAuthType": "httpHeaderAuth",
  // Header: "Authorization" = "token ghp_xxxxxxxxx"
  "queryParameters": {
    "per_page": 100,                // 每页 100 条 (GitHub 最大值)
    "page": "={{ $pageCount + 1 }}" // 页码从 1 开始
  },
  "options": {
    "pagination": {
      "paginationMode": "updateAParameterInEachRequest",
      "parameter": "page",
      "maxPages": 500               // 最多取 50000 个 Stars
    },
    "response": {
      "neverError": true
    }
  }
}

// 停止条件表达式:
// {{ $response.body.length < 100 }}
// 当返回不足 100 条时,说明已经是最后一页

下一步

在 Ep 09 中,我们将解锁 n8n 最强大的兜底节点——Code Node,学习在工作流中直接编写 JavaScript 与 Python 处理任何复杂数据结构。