跳转到内容
搜索文档

http

最后更新 查看 MarkdownAgent 设置

兼容性标志

客户端方法

要使用 HTTP 客户端方法(http.gethttp.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.createServerhttp.Serverhttp.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 请求,无需手动配置请求选项。

由于 getfetch(...) 的封装,它只能在导出的 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 用于发送请求数据。

由于 requestfetch(...) 的封装,它只能在导出的 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 流类

ClientRequestServerResponse 均继承自 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,仅包含以下属性:encryptedremoteFamilyremoteAddressremotePortlocalAddresslocalPortdestroy() 方法。
  • 以下 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(或 nullundefined)将分配随机端口号。

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 文档
  • 不支持以下服务器选项:maxHeaderSizeinsecureHTTPParserkeepAliveTimeoutconnectionsCheckingInterval

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

这篇文档对您有帮助吗?