返回文章列表

文章

HTTP/2在本地开发测试时的多种解决方案

目录
  1. 1. 使用自签名证书(最常用)
  2. 生成自签名证书
  3. Node.js 开发服务器配置
  4. 2. 使用 mkcert(推荐)
  5. 安装和使用
  6. 在代码中使用
  7. 3. 开发工具内置支持
  8. Webpack Dev Server
  9. Create React App
  10. Vite
  11. 4. 浏览器特殊处理
  12. Chrome 本地开发豁免
  13. 访问自签名证书站点
  14. 5. Docker 开发环境
  15. Docker Compose 配置
  16. 6. 实际开发工作流示例
  17. 完整的开发环境设置
  18. Express + HTTP/2 开发配置
  19. 7. 最佳实践总结
  20. 开发环境证书管理
  21. 环境特定的配置
  22. 8. 常见问题解决
  23. 证书信任问题
  24. 端口被占用

1. 使用自签名证书(最常用)#

生成自签名证书#

# 生成私钥
openssl genrsa -out localhost.key 2048

# 生成证书签名请求
openssl req -new -key localhost.key -out localhost.csr \\
  -subj "/C=US/ST=State/L=City/O=Organization/CN=localhost"

# 生成自签名证书(有效期365天)
openssl x509 -req -days 365 -in localhost.csr -signkey localhost.key -out localhost.crt

Node.js 开发服务器配置#

const http2 = require('http2');
const fs = require('fs');

const server = http2.createSecureServer({
  key: fs.readFileSync('./localhost.key'),
  cert: fs.readFileSync('./localhost.crt')
});

server.on('stream', (stream, headers) => {
  stream.respond({
    'content-type': 'text/html',
    ':status': 200
  });
  stream.end('<h1>Hello HTTP/2 with self-signed cert!</h1>');
});

server.listen(8443, () => {
  console.log('HTTP/2 server running on <https://localhost:8443>');
  console.log('Note: Browser will show security warning for self-signed certificate');
});

2. 使用 mkcert(推荐)#

mkcert 可以生成浏览器信任的本地证书:

安装和使用#

# 安装 mkcert (Mac)
brew install mkcert

# 或 Linux
sudo apt install libnss3-tools
wget -O mkcert <https://github.com/FiloSottile/mkcert/releases/download/v1.4.4/mkcert-v1.4.4-linux-amd64>
chmod +x mkcert
sudo mv mkcert /usr/local/bin/

# 初始化(安装本地CA)
mkcert -install

# 为项目生成证书
mkcert localhost 127.0.0.1 ::1

# 生成的文件:
# localhost+2.pem (证书)
# localhost+2-key.pem (私钥)

在代码中使用#

const http2 = require('http2');
const fs = require('fs');

const server = http2.createSecureServer({
  key: fs.readFileSync('./localhost+2-key.pem'),
  cert: fs.readFileSync('./localhost+2.pem')
});

server.listen(8443, () => {
  console.log('HTTP/2 server running on <https://localhost:8443>');
  console.log('This certificate is trusted by browsers!');
});

3. 开发工具内置支持#

Webpack Dev Server#

// webpack.config.js
module.exports = {
  devServer: {
    https: true, // 自动生成证书
    http2: true
  }
};

// 或使用自定义证书
module.exports = {
  devServer: {
    https: {
      key: fs.readFileSync('./localhost.key'),
      cert: fs.readFileSync('./localhost.crt')
    },
    http2: true
  }
};

Create React App#

# 设置环境变量使用HTTPS
HTTPS=true npm start

# 或使用自定义证书
HTTPS=true SSL_CRT_FILE=localhost.crt SSL_KEY_FILE=localhost.key npm start

Vite#

// vite.config.js
import { defineConfig } from 'vite'
import fs from 'fs'

export default defineConfig({
  server: {
    https: {
      key: fs.readFileSync('./localhost.key'),
      cert: fs.readFileSync('./localhost.crt')
    }
  }
})

4. 浏览器特殊处理#

Chrome 本地开发豁免#

# 启动Chrome时禁用证书验证(仅开发环境!)
google-chrome --ignore-certificate-errors-spki-list --ignore-certificate-errors --ignore-ssl-errors --allow-running-insecure-content

访问自签名证书站点#

当访问使用自签名证书的 https://localhost 时:

  1. 浏览器显示"不安全连接"警告
  2. 点击"高级"
  3. 点击"继续前往localhost(不安全)"
  4. 或者直接键盘输入 ****thisisunsafe(Chrome快捷方式)

5. Docker 开发环境#

Docker Compose 配置#

version: '3.8'
services:
  app:
    build: .
    ports:
      - "8443:8443"
    volumes:
      - ./certs:/app/certs  # 挂载证书
    environment:
      - SSL_CERT_PATH=/app/certs/localhost.crt
      - SSL_KEY_PATH=/app/certs/localhost.key

6. 实际开发工作流示例#

完整的开发环境设置#

# 1. 安装 mkcert 并生成证书
mkcert -install
mkcert localhost 127.0.0.1 ::1 myapp.test

# 2. 启动开发服务器
npm run dev

# 3. 访问 <https://localhost:3000> (浏览器自动信任)

Express + HTTP/2 开发配置#

const express = require('express');
const http2 = require('http2');
const fs = require('fs');
const spdy = require('spdy'); // 或者使用spdy包

const app = express();

app.get('/', (req, res) => {
  res.send('Hello HTTP/2!');
});

// 开发环境:使用自签名证书
const options = {
  key: fs.readFileSync('./localhost+2-key.pem'),
  cert: fs.readFileSync('./localhost+2.pem'),
  allowHTTP1: true // 允许HTTP/1.1回退
};

// 生产环境:使用真实证书
// const options = {
//   key: fs.readFileSync('/etc/ssl/private/private.key'),
//   cert: fs.readFileSync('/etc/ssl/certs/certificate.crt')
// };

spdy.createServer(options, app).listen(8443, () => {
  console.log('HTTP/2 Express server running on <https://localhost:8443>');
});

7. 最佳实践总结#

开发环境证书管理#

# 推荐的项目结构
project/
├── certs/                 # 证书目录(添加到.gitignore)
│   ├── localhost+2.pem
│   └── localhost+2-key.pem
├── src/
├── package.json
└── README.md

环境特定的配置#

// config/ssl.js
const fs = require('fs');
const path = require('path');

const isDevelopment = process.env.NODE_ENV === 'development';

const sslConfig = isDevelopment ? {
  // 开发环境:自签名证书
  key: fs.readFileSync(path.join(__dirname, '../certs/localhost+2-key.pem')),
  cert: fs.readFileSync(path.join(__dirname, '../certs/localhost+2.pem'))
} : {
  // 生产环境:真实证书
  key: fs.readFileSync(process.env.SSL_KEY_PATH),
  cert: fs.readFileSync(process.env.SSL_CERT_PATH)
};

module.exports = sslConfig;

8. 常见问题解决#

证书信任问题#

# 如果证书不被信任,重新安装mkcert的CA
mkcert -uninstall  # 先卸载
mkcert -install    # 重新安装

端口被占用#

# 查找占用端口的进程
lsof -i :8443

# 或者使用不同的端口
server.listen(3443, () => {
  console.log('Server running on <https://localhost:3443>');
});

总结:对于本地HTTP/2开发,推荐使用 mkcert 生成浏览器信任的本地证书,这样既保证了开发体验,又能够完全测试HTTP/2的所有特性。这是目前最优雅的本地开发解决方案。