要使用 HTTP 客户端方法(http.get、http.request 等),除 nodejs_compat 标志外,还必须启用 enable_nodejs_http_modules 兼容性标志。
当启用 nodejs_compat 时,使用兼容性日期为 2025-08-15 或更晚的 Worker 会自动启用此标志。对于使用较早兼容性日期的 Worker,可在 Wrangler 配置文件中手动添加该标志:
{
"compatibility_flags": [
"nodejs_compat",
"enable_nodejs_http_modules"
]
}compatibility_flags = [ "nodejs_compat", "enable_nodejs_http_modules" ]要使用 HTTP 服务端方法(http.createServer、http.Server、http.ServerResponse),除 nodejs_compat 标志外,还必须启用 enable_nodejs_http_server_modules 兼容性标志。
当启用 nodejs_compat 时,使用兼容性日期为 2025-09-01 或更晚的 Worker 会自动启用此标志。对于使用较早兼容性日期的 Worker,可在 Wrangler 配置文件中手动添加该标志:
{
"compatibility_flags": [
"nodejs_compat",
"enable_nodejs_http_server_modules"
]
}compatibility_flags = [ "nodejs_compat", "enable_nodejs_http_server_modules" ]要同时使用客户端和服务端方法,请启用两个标志:
{
"compatibility_flags": [
"nodejs_compat",
"enable_nodejs_http_modules",
"enable_nodejs_http_server_modules"
]
}compatibility_flags = [
"nodejs_compat",
"enable_nodejs_http_modules",
"enable_nodejs_http_server_modules"
]Node.js http.get ↗ 方法的实现。
get 方法向指定 URL 执行 GET 请求并调用回调处理响应。它是便捷方法,可简化 HTTP GET 请求,无需手动配置请求选项。
由于 get 是 fetch(...) 的封装,它只能在导出的 fetch 或类似处理器内使用。在此类处理器之外使用 get 会抛出错误。
import { get } from "node:http";
export default {
async fetch() {
const { promise, resolve, reject } = Promise.withResolvers();
get("http://example.org", (res) => {
let data = "";
res.setEncoding("utf8");
res.on("data", (chunk) => {
data += chunk;
});
res.on("end", () => {
resolve(new Response(data));
});
res.on("error", reject);
}).on("error", reject);
return promise;
},
};Workers 中 get 的实现是对全局 fetch API 的封装,因此受相同的限制约束。
如上例所示,需要在 fetch 处理器中使用 Promise 正确等待请求,否则处理器返回时 fetch 可能被过早取消。
Node.js `http.request' ↗ 方法的实现。
request 方法创建 HTTP 请求,可自定义 method、headers 和 body 等选项。它提供对请求配置的完全控制,并返回 Node.js stream.Writable 用于发送请求数据。
由于 request 是 fetch(...) 的封装,它只能在导出的 fetch 或类似处理器内使用。在此类处理器之外使用 request 会抛出错误。
import { get } from "node:http";
export default {
async fetch() {
const { promise, resolve, reject } = Promise.withResolvers();
get(
{
method: "GET",
protocol: "http:",
hostname: "example.org",
path: "/",
},
(res) => {
let data = "";
res.setEncoding("utf8");
res.on("data", (chunk) => {
data += chunk;
});
res.on("end", () => {
resolve(new Response(data));
});
res.on("error", reject);
},
)
.on("error", reject)
.end();
return promise;
},
};由于 Cloudflare Workers 将 node:http 实现为全局 fetch API 的封装,传递给 request(和 get)方法的以下选项不受支持:
maxHeaderSizeinsecureHTTPParsercreateConnectionlookupsocketPath
OutgoingMessage ↗ 类表示发送给客户端的 HTTP 响应。它提供写入响应头和正文以及结束响应的方法。OutgoingMessage 继承自 Node.js stream.Writable 流类。
OutgoingMessage 类是传出 HTTP 消息(请求和响应)的基类。它提供写入头和正文数据以及结束消息的方法。OutgoingMessage 继承自 Writable 流类 ↗。
ClientRequest 和 ServerResponse 均继承自 OutgoingMessage。
IncomingMessage 类表示从客户端接收的 HTTP 请求。它提供读取请求头和正文以及结束请求的方法。IncomingMessage 继承自 Readable 流类。
IncomingMessage 类表示 HTTP 消息(请求或响应)。它提供读取头和正文数据的方法。IncomingMessage 继承自 Readable 流类。
import { get, IncomingMessage } from "node:http";
import { ok, strictEqual } from "node:assert";
export default {
async fetch() {
// ...
get("http://example.org", (res) => {
ok(res instanceof IncomingMessage);
});
// ...
},
};Workers 实现在 IncomingMessage 对象上包含 cloudflare 属性:
import { createServer } from "node:http";
import { httpServerHandler } from "cloudflare:node";
const server = createServer((req, res) => {
console.log(req.cloudflare.cf.country);
console.log(req.cloudflare.cf.ray);
res.write("Hello, World!");
res.end();
});
server.listen(8080);
export default httpServerHandler({ port: 8080 });cloudflare.cf 属性包含 Cloudflare 特定请求属性。
Workers 实现与 Node.js 之间存在以下差异:
- 不支持 trailer 头
socket属性不继承自net.Socket,仅包含以下属性:encrypted、remoteFamily、remoteAddress、remotePort、localAddress、localPort和destroy()方法。- 以下
socket属性的行为与 Node.js 对应项不同:- 本地运行时
remoteAddress将返回127.0.0.1 remotePort将返回 2^15 到 2^16 之间的随机端口号- 若存在请求的
host头,localAddress将返回其值;否则返回127.0.0.1 localPort将返回分配给服务器实例的端口号req.socket.destroy()会转发到req.destroy()
- 本地运行时
Node.js `http.Agent' ↗ 类的部分实现。
Agent 通过为每个 host/port 维护请求队列来管理 HTTP 连接复用。然而在 Workers 环境中,此类网络连接、端口等的底层管理并不相关,因为由 Cloudflare 基础设施处理。因此,Workers 中的 Agent 实现是桩实现,不支持连接池或 keep-alive。
import { Agent } from "node:http";
import { strictEqual } from "node:assert";
const agent = new Agent();
strictEqual(agent.protocol, "http:");Node.js http.createServer ↗ 方法的实现。
createServer 方法创建可处理传入请求的 HTTP 服务器实例。
import { createServer } from "node:http";
import { httpServerHandler } from "cloudflare:node";
const server = createServer((req, res) => {
res.writeHead(200, { "Content-Type": "text/plain" });
res.end("Hello from Node.js HTTP server!");
});
server.listen(8080);
export default httpServerHandler({ port: 8080 });httpServerHandler 函数将 Node.js HTTP 服务器与 Cloudflare Workers 请求模型集成。它支持两种 API 模式:
import http from "node:http";
import { httpServerHandler } from "cloudflare:node";
const server = http.createServer((req, res) => {
res.end("hello world");
});
// Pass server directly (simplified) - automatically calls listen() if needed
export default httpServerHandler(server);
// Or use port-based routing for multiple servers
server.listen(8080);
export default httpServerHandler({ port: 8080 });该处理器自动将传入的 Worker 请求路由到你的 Node.js 服务器。使用基于端口的路由时,端口号作为路由键,决定哪个服务器处理请求,允许同一 Worker 中的多个服务器共存。
若要更直接地控制请求路由,可使用 cloudflare:node 中的 handleAsNodeRequest 函数。该函数将 Worker 请求直接路由到在特定端口上运行的 Node.js 服务器:
import { createServer } from "node:http";
import { handleAsNodeRequest } from "cloudflare:node";
const server = createServer((req, res) => {
res.writeHead(200, { "Content-Type": "text/plain" });
res.end("Hello from Node.js HTTP server!");
});
server.listen(8080);
export default {
fetch(request) {
return handleAsNodeRequest(8080, request);
},
};这种方式让你在仍利用 Node.js HTTP 服务器处理请求的同时,完全控制 fetch 处理器。
Node.js http.Server ↗ 类的实现。
Server 类表示 HTTP 服务器,提供处理传入请求的方法。它继承 Node.js EventEmitter 类,可用于创建自定义服务器实现。
使用 httpServerHandler 时,server.listen() 中指定的端口号作为路由键而非实际网络端口。处理器使用该端口决定哪个 HTTP 服务器实例应处理传入请求,允许同一 Worker 内通过不同端口号标识多个服务器。使用端口值 0(或 null 或 undefined)将分配随机端口号。
import { Server } from "node:http";
import { httpServerHandler } from "cloudflare:node";
const server = new Server((req, res) => {
res.writeHead(200, { "Content-Type": "application/json" });
res.end(JSON.stringify({ message: "Hello from HTTP Server!" }));
});
server.listen(8080);
export default httpServerHandler({ port: 8080 });Workers 实现与 Node.js 之间存在以下差异:
- 未实现
closeAllConnections()和closeIdleConnections()等连接管理方法 - 仅支持带端口号或无参数的
listen()变体:listen()、listen(0, callback)、listen(callback)等。参考 Node.js 文档 ↗。 - 不支持以下服务器选项:
maxHeaderSize、insecureHTTPParser、keepAliveTimeout、connectionsCheckingInterval
Node.js http.ServerResponse ↗ 类的实现。
ServerResponse 类表示传递给请求处理器的服务端响应对象。它提供写入响应头和正文数据的方法,并继承 Node.js Writable 流类。
import { createServer, ServerResponse } from "node:http";
import { httpServerHandler } from "cloudflare:node";
import { ok } from "node:assert";
const server = createServer((req, res) => {
ok(res instanceof ServerResponse);
// Set multiple headers at once
res.writeHead(200, {
"Content-Type": "application/json",
"X-Custom-Header": "Workers-HTTP",
});
// Stream response data
res.write('{"data": [');
res.write('{"id": 1, "name": "Item 1"},');
res.write('{"id": 2, "name": "Item 2"}');
res.write("]}");
// End the response
res.end();
});
export default httpServerHandler(server);Workers 实现中不支持以下方法和功能:
- 不可用
assignSocket()和detachSocket()方法 - 不支持 trailer 头
- 不可用
writeContinue()和writeEarlyHints()方法 - 一般不支持 1xx 响应
由于 Workers 的 node:http 实现是对全局 fetch API 的封装,与标准 Node.js 环境相比存在行为差异和限制:
- 不使用
Connection头。Workers 将自动管理连接。 Content-Length头的处理方式与fetchAPI 相同。若提供了 body,头将自动设置,手动设置的值将被忽略。- 不支持
Expect: 100-continue头。 - 不支持 trailing 头。
- 不支持
'continue'事件。 - 不支持
'information'事件。 - 不支持
'socket'事件。 - 不支持
'upgrade'事件。 - 不支持直接访问底层
socket。