在 Web 开发领域,获取实时数据对于构建现代化的交互式应用程序至关重要。传统的 API 需要您不断请求新信息,而 Webhook 则颠覆了这种模式,在事件发生时立即推送数据。本指南提供了一个全面的Webhook 示例,引导您了解使用 NodeJS 创建 Webhook 接收器的概念、创建方法和测试方法。
我们将深入剖析 Webhook 的工作原理,构建一个简单实用的 Express.js 应用程序来处理传入的 Webhook 请求,并使用 Tunnelmole 将本地开发服务器公开到公共互联网进行端到端测试。最终,您将对 Webhook 的集成到您自己的项目中拥有扎实的理解和实践基础。
什么是 Webhook?“反向 API”详解
Webhook 的核心是当特定事件发生时,一个应用程序会自动向另一个应用程序发送一条消息。您可以将其视为“用户定义的 HTTP 回调”。您的应用程序无需每隔几分钟轮询一次 API 来询问“是否有新数据?”,而是 POST
在数据可用时,服务提供商会直接向您指定的 URL(即 Webhook URL)发送请求。
这种“推”的模式比传统 API 的“拉”的模式效率高得多。
- 拉取模型(传统 API):您的应用程序负责向服务器发出请求以获取信息。这就像每小时给邮局打电话询问是否有邮件一样。这会占用大量资源,并且可能导致数据接收延迟。
- 推送模型(Webhook):服务器负责在事件发生时向您的应用程序发送信息。邮件到达后,邮局会立即将其直接投递到您的邮箱。这种方式高效,能够近乎实时地提供数据,并减少不必要的网络流量。
常见的 Webhook 用例
Webhook 是现代自动化和集成的支柱。以下是一些实际示例:
- 支付网关:当客户付款成功、订阅取消或出现争议时,Stripe 会发送一个 webhook。
- 版本控制: GitHub 使用 Webhook 通知其他服务有关代码推送、拉取请求或新问题等事件。这就是 CI/CD 流水线(例如 Jenkins 或 GitHub Actions)自动触发的方式。
- 电子商务平台:当下达新订单、库存水平发生变化或客户更新其信息时,Shopify 可以发送 webhook。
- 通讯工具: Slack 可以接收 webhook 以将消息发布到频道中,而 Twilio 使用它们来通知您的应用程序有关传入的短信或电话。
为了在开发过程中处理这些传入的请求,您的应用程序(通常在 上运行localhost
)需要能够被这些外部服务访问。这时,隧道工具就变得至关重要。

如图所示,像 Tunnelmole 这样的服务会创建一个从互联网上的公共 URL 到您本地计算机上运行的应用程序的安全连接。Webhook 提供程序将其请求发送到公共 URL,Tunnelmole 将其转发到您的本地应用程序,然后您就可以实时调试和处理它。
先决条件
在构建 webhook 示例之前,请确保您的系统上安装了以下工具:
- Node.js 和 npm:从 Node.js 官方网站 下载并安装。npm 是 Node 包管理器,与安装捆绑在一起。
- 代码编辑器:任何文本编辑器都可以,但 Visual Studio Code 是 JavaScript 开发的热门选择。
- Tunnelmole:一个简单的开源命令行工具,用于为本地服务器创建公共 URL。
您可以使用单个命令安装 Tunnelmole。
对于 Linux 和 macOS:
curl -O https://install.tunnelmole.com/xD345/install && sudo bash install
对于 Windows:
- 下载 tmole.exe。
- 将可执行文件放在系统的文件夹中
PATH
。
现在,让我们开始构建。
构建我们的 Webhook 示例:NodeJS 和 Express 应用程序
POST
我们将使用 Express.js(Node.js 最流行的 Web 框架)创建一个简单的服务器。该服务器将在特定端点上监听传入的请求。
步骤 1:设置项目
首先,为您的项目创建一个新目录并使用 npm 初始化它。
mkdir webhook-receiver-example
cd webhook-receiver-example
npm init -y
这将创建一个 package.json
文件。现在,让我们安装 Express 和body-parser
,这是一个用于解析传入请求主体的中间件。
npm install express body-parser
第 2 步:编写 Express 服务器代码
在你的项目目录中创建一个名为的文件 index.js
并添加以下代码:
const express = require('express');
const bodyParser = require('body-parser');
// Initialize the Express app
const app = express();
const port = 3000;
// Use body-parser middleware to parse JSON request bodies
app.use(bodyParser.json());
// Define a welcome message for the root URL
app.get('/', (req, res) => {res.send('Welcome to the Webhook Receiver! Use the /webhook-example endpoint for POST requests.');
});
/**
* This is our main webhook handler endpoint.
* It listens for POST requests and logs the received body.
*/
app.post('/webhook-example', (req, res) => {console.log('--- New Webhook Received ---');
// The webhook payload is in the request body
const payload = req.body;
console.log('Headers:', JSON.stringify(req.headers, null, 2));
console.log('Payload:', JSON.stringify(payload, null, 2));
// You can add your processing logic here.
// For example, save data to a database, trigger an email, etc.
// Respond to the webhook provider to acknowledge receipt
res.status(200).send('Webhook received successfully!');
});
// Start the server and listen for connections
app.listen(port, () => {console.log(`Server is running on http://localhost:${port}`);
console.log('Listening for webhooks at the /webhook-example endpoint.');
});
让我们分解一下这段代码:
- 我们进口
express
和body-parser
。 app.use(bodyParser.json());
告诉 Express 自动解析传入的 JSON 格式的请求主体。大多数 webhook 提供商都是通过这种方式发送数据的。- 该
app.post('/webhook-example', ...)
块定义了我们的 webhook 处理程序。它仅响应POST
发送到/webhook-example
URL 的请求。 - 在处理程序内部,我们将请求标头和有效负载(
req.body
)记录到控制台。在这里您可以看到 Webhook 提供程序发送的数据。 - 最后,
res.status(200).send(...)
向服务提供者发送成功响应。这一点很重要——如果服务提供者没有收到200 OK
状态信息,它可能会认为传输失败,并尝试再次发送 webhook。
步骤 3:运行服务器
通过在终端中运行以下命令来启动本地服务器:
node index.js
您应该看到输出:
Server is running on http://localhost:3000
Listening for webhooks at the /webhook-example endpoint.
您的 Webhook 接收器现已在本地运行,但无法通过互联网访问。让我们来解决这个问题。
步骤 4:使用 Tunnelmole 公开您的本地服务器
在 Node.js 服务器运行时,打开一个 新的终端窗口 并运行 Tunnelmole 以获取公共 URL。
tmole 3000
Tunnelmole 将连接到其服务并生成一个转发到本地端口的公共 URL 3000
。输出将如下所示:
Your Tunnelmole Public URLs are below and are accessible internet wide. Always use HTTPs for the best security
https://k29d1m-ip-XX-XX-XX-XX.tunnelmole.net ⟶ http://localhost:3000
http://k29d1m-ip-XX-XX-XX-XX.tunnelmole.net ⟶ http://localhost:3000
获取 HTTPS URL。这是您的公共 Webhook URL。在本例中,我们的完整 Webhook 端点是https://k29d1m-ip-XX-XX-XX-XX.tunnelmole.net/webhook-example
。
为什么选择 Tunnelmole?透明度和控制力
使用 Tunnelmole 的一大优势在于其对开源的承诺。您刚刚安装的客户端及其连接的服务器均完全开源。这为开发者带来了两大益处:
- 透明度:您可以自己检查代码,以准确了解其工作原理并确保其符合您的安全标准。
- 自托管:为了最大限度地控制和保护隐私,您可以在自己的基础架构上托管 Tunnelmole 服务。这对于数据政策严格的企业环境或喜欢自行管理工具的开发者来说是理想的选择。
步骤 5:测试 Webhook
现在到了激动人心的部分——让我们向公共 URL 发送一个测试 webhook,看看一切是否正常。我们可以使用一个简单的 curl
命令来模拟 webhook 提供程序。
打开 第三个终端窗口 并运行以下命令。请确保将占位符 URL 替换为实际的 Tunnelmole URL。
curl -X POST \
https://YOUR-UNIQUE-SUBDOMAIN.tunnelmole.net/webhook-example \
-H 'Content-Type: application/json' \
-H 'X-Custom-Header: TestFromCurl' \
-d '{"event_type":"user.created","timestamp":"'$(date -u +"%Y-%m-%dT%H:%M:%SZ")'","data": {"user_id":"usr_12345","name":"Jane Doe","email":"[email protected]"}
}'
如果成功,curl
将会打印Webhook received successfully!
。
现在,查看应用程序正在运行的终端index.js
。您应该看到来自 webhook 的记录输出:
--- New Webhook Received ---
Headers: {
"content-type": "application/json",
"x-custom-header": "TestFromCurl",
"host": "k29d1m-ip-XX-XX-XX-XX.tunnelmole.net",
"accept": "*/*",
"content-length": "164",
...
}
Payload: {
"event_type": "user.created",
"timestamp": "2025-07-15T10:30:00Z",
"data": {
"user_id": "usr_12345",
"name": "Jane Doe",
"email": "[email protected]"
}
}
恭喜!您已成功从头到尾构建、公开并测试了 webhook 接收器。
扩展示例:生产注意事项
这个 webhook 示例提供了坚实的基础,但对于实际应用程序,您需要考虑更多事项,尤其是安全性。
保护你的 Webhook
由于您的 webhook URL 是公开的,任何人都可能向其发送请求。为了确保传入的数据来自可信来源,您必须 验证 webhook 签名。
X-Hub-Signature-256
大多数 webhook 提供商(例如 GitHub 和 Stripe)都会在请求标头中包含加密签名Stripe-Signature
。此签名通常是通过使用只有您和提供商知道的密钥对请求有效负载进行哈希处理而生成的。
您的 webhook 处理程序应该:
- 从请求标头中读取签名。
- 使用接收到的有效载荷和存储的密钥计算其自己的签名。
- 比较两个签名。如果不匹配,则拒绝该请求。
这可以防止攻击者向您的端点发送伪造的有效载荷。
结论
Webhook 是构建事件驱动型实时应用程序的强大工具。通过推送数据而非等待数据被拉取,Webhook 实现了服务之间高效且即时的通信。在本指南中,我们讲解了一个完整的Webhook 示例,从在 Node.js 中创建监听器,到使用开源工具 Tunnelmole 公开监听器,并测试了整个流程。
关键要点如下:
- Webhook 是由事件触发的 HTTP POST 请求。
- 在本地开发期间,您需要一个公共 URL 来接收 webhook,而 Tunnelmole 提供了一种简单的开源方法来获取它。
- 始终以
200 OK
状态响应以确认收到。 - 对于生产用途,通过验证签名来保护您的 webhook 端点是不可协商的。
有了这些知识,您现在就可以开始将 Stripe、Shopify、GitHub 等服务的 webhook 集成到您自己的项目中。