You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何将NestJS服务器从HTTP/1升级至HTTP/2?

NestJS HTTP/2 升级指南及问题解析

NestJS 是否内置 HTTP/2 支持?

NestJS 本身不直接实现 HTTP/2,但它依赖的底层 HTTP 服务器(Express 或 Fastify)支持 HTTP/2:

  • Express: 需要借助额外工具(推荐 Node 原生 http2 模块,替代已废弃的 spdy)实现 HTTP/2 连接,但 Express 核心未原生适配 HTTP/2,请求对象仍会以 HTTP/1.1 格式暴露。
  • Fastify: 原生支持 HTTP/2,无需额外依赖,且能直接提供 HTTP/2 兼容的请求/响应对象。

你当前问题的原因

你使用 spdy 创建 HTTP/2 服务器并挂载 Express 应用时,spdy 会将 HTTP/2 请求转换为 Express 能识别的 HTTP/1.1 请求格式。因此:

  • 浏览器与服务器的连接确实是 HTTP/2(所以网络标签页显示正确)
  • 但 Nest/Express 中拿到的 req 对象是经过转换的 HTTP/1.1 版本,因此打印时显示 HTTP/1

正确升级到 HTTP/2 的两种方案

方案一:基于 Express + Node 原生 http2 模块(适配现有代码)

由于 spdy 已废弃,建议使用 Node 内置的 http2 模块。步骤如下:

  1. 无需额外安装依赖(http2 是 Node 核心模块)
  2. 修改 bootstrap 函数:
import * as http2 from 'http2';
import { NestExpressApplication } from '@nestjs/platform-express';
import { ExpressAdapter } from '@nestjs/platform-express/adapters/express-adapter';
import * as fs from 'fs';
import { NestFactory, Logger } from '@nestjs/core';
import { AppModule } from './app.module';
import * as morgan from 'morgan';
import * as compression from 'compression';
import * as bodyParser from 'body-parser';

async function bootstrap() {
  const httpsOptions = {
    key: fs.readFileSync('/etc/secrets/server.key'),
    cert: fs.readFileSync('/etc/secrets/server.crt'),
  };

  const expressApp = require('express')();
  const app: NestExpressApplication = await NestFactory.create(
    AppModule,
    new ExpressAdapter(expressApp),
    { bufferLogs: true },
  );

  // 保留现有配置
  const corsUrl = process.env.CORS_URL?.split(',') || [];
  app.enableCors({ origin: corsUrl, allowedHeaders: '*', methods: '*' });

  const nestLogger = new Logger('HTTP REQUEST');
  app.use(morgan(':method :url :status - :response-time ms', {
    stream: { write: (message: string) => nestLogger.log(message.trim()) },
  }));
  app.use(compression());
  app.use(bodyParser.json({ limit: '50mb' }));
  app.use(bodyParser.urlencoded({ limit: '50mb', extended: true }));

  app.use((req, res, next) => {
    res.setHeader('Content-Security-Policy', "script-src 'self'");
    res.setHeader('X-XSS-Protection', '1; mode=block');
    res.setHeader('X-Frame-Options', 'DENY');
    res.setHeader('X-Content-Type-Options', 'nosniff');
    res.setHeader('Strict-Transport-Security', 'max-age=31536000; includeSubDomains; preload');
    next();
  });

  await app.init();

  // 创建 HTTP/2 服务器并挂载 Express 应用
  const server = http2.createSecureServer(httpsOptions, expressApp);
  server.listen(8443, () => {
    console.log('Server running on https://localhost:8443 (HTTP/2)');
  });
}

bootstrap();

注意:此方案下,Express 请求对象仍会显示 HTTP/1.1,这是正常现象——连接层是 HTTP/2,但应用层仍用 HTTP/1.1 兼容格式。

方案二:基于 Fastify(推荐,原生 HTTP/2 支持)

Fastify 对 HTTP/2 有原生支持,能直接提供 HTTP/2 请求对象,步骤更简洁:

  1. 安装依赖:
npm install @nestjs/platform-fastify fastify fastify-morgan
  1. 修改 bootstrap 函数:
import { NestFactory, Logger } from '@nestjs/core';
import {
  FastifyAdapter,
  NestFastifyApplication,
} from '@nestjs/platform-fastify';
import { AppModule } from './app.module';
import * as fs from 'fs';
import fastifyMorgan from 'fastify-morgan';

async function bootstrap() {
  const httpsOptions = {
    key: fs.readFileSync('/etc/secrets/server.key'),
    cert: fs.readFileSync('/etc/secrets/server.crt'),
    allowHTTP1: true, // 可选:兼容 HTTP/1 请求
  };

  const app = await NestFactory.create<NestFastifyApplication>(
    AppModule,
    new FastifyAdapter({ https: httpsOptions, http2: true }),
    { bufferLogs: true },
  );

  // 配置 CORS
  const corsUrl = process.env.CORS_URL?.split(',') || [];
  app.enableCors({
    origin: corsUrl,
    allowedHeaders: '*',
    methods: '*',
  });

  // 替换 morgan 为 fastify-morgan
  const nestLogger = new Logger('HTTP REQUEST');
  await app.register(fastifyMorgan(':method :url :status - :response-time ms', {
    stream: { write: (message: string) => nestLogger.log(message.trim()) },
  }));

  // Fastify 内置压缩,无需额外 compression 中间件
  app.register(require('@fastify/compress'));

  // 配置请求体大小限制
  app.register(require('@fastify/formbody'), { bodyLimit: 52428800 }); // 50MB
  app.register(require('@fastify/json'), { bodyLimit: 52428800 });

  // 设置安全头
  app.addHook('onRequest', (request, reply, done) => {
    reply.header('Content-Security-Policy', "script-src 'self'");
    reply.header('X-XSS-Protection', '1; mode=block');
    reply.header('X-Frame-Options', 'DENY');
    reply.header('X-Content-Type-Options', 'nosniff');
    reply.header('Strict-Transport-Security', 'max-age=31536000; includeSubDomains; preload');
    done();
  });

  await app.listen({ port: 8443 });
  console.log('Server running on https://localhost:8443 (HTTP/2)');
}

bootstrap();

此方案下,req 对象会正确显示 HTTP/2 协议,且性能更优。

额外注意事项

  • 确保 SSL 证书有效(HTTP/2 强制要求 HTTPS)
  • 若使用反向代理(如 Nginx),需配置代理支持 HTTP/2 并正确转发协议信息
  • Fastify 部分中间件与 Express 不兼容,需替换为 Fastify 生态对应组件

内容的提问来源于stack exchange,提问作者Muhammad Omer Hussain

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.17 00:12:32