跳转到内容
搜索文档

http

最后更新 查看 MarkdownAgent 设置

兼容性标志

客户端方法

要使用 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"
]

get

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 可能被过早取消。

request

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)方法的以下选项不受支持:

  • maxHeaderSize
  • insecureHTTPParser
  • createConnection
  • lookup
  • socketPath

OutgoingMessage

OutgoingMessage ↗ 类表示发送给客户端的 HTTP 响应。它提供写入响应头和正文以及结束响应的方法。OutgoingMessage 继承自 Node.js stream.Writable 流类。

OutgoingMessage 类是传出 HTTP 消息(请求和响应)的基类。它提供写入头和正文数据以及结束消息的方法。OutgoingMessage 继承自 Writable 流类 ↗。

ClientRequest 和 ServerResponse 均继承自 OutgoingMessage。

IncomingMessage

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()

Agent

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:");

createServer

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 });

Node.js 集成

httpServerHandler

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 中的多个服务器共存。

handleAsNodeRequest

若要更直接地控制请求路由,可使用 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 处理器。

Server

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

ServerResponse

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 响应

Node.js 与 Workers node:http 实现的其他差异

由于 Workers 的 node:http 实现是对全局 fetch API 的封装,与标准 Node.js 环境相比存在行为差异和限制:

  • 不使用 Connection 头。Workers 将自动管理连接。
  • Content-Length 头的处理方式与 fetch API 相同。若提供了 body,头将自动设置,手动设置的值将被忽略。
  • 不支持 Expect: 100-continue 头。
  • 不支持 trailing 头。
  • 不支持 'continue' 事件。
  • 不支持 'information' 事件。
  • 不支持 'socket' 事件。
  • 不支持 'upgrade' 事件。
  • 不支持直接访问底层 socket。

这篇文档对您有帮助吗?