大多数前端开发者认为需要在本地运行 HTTPS 才能使用 Service Worker 或地理定位等浏览器 API。这实际上是一个误解——浏览器已经将 localhost 视为安全上下文,因此这些 API 在纯 HTTP 下也能正常工作。但确实存在一些真正需要本地 HTTPS 的场景:测试 OAuth 回调 URL、在类生产环境中处理 Cookie、使用自定义主机名开发,或精确匹配生产环境行为。本文将向您展示如何干净利落地完成这些设置。
核心要点
- 浏览器将
localhost视为安全上下文,因此大多数安全上下文 API 在本地无需 HTTPS 即可工作。 - 本地 HTTPS 适用于测试类生产环境的 Cookie 行为、OAuth 回调、自定义主机名或移动设备访问。
- 自签名证书会导致持续的浏览器警告——应使用
mkcert创建受信任的本地证书颁发机构。 - 切勿提交
rootCA-key.pem文件,如果 Node.js 需要信任您的本地 CA,请设置NODE_EXTRA_CA_CERTS。
何时真正需要本地 HTTPS
在使用证书之前,先问问自己是否真的需要。所有主流浏览器都将 http://localhost 视为潜在可信源。Service Worker、摄像头访问和大多数安全上下文 API 无需任何 HTTPS 设置即可工作。您可以在 webstatus.dev 的浏览器兼容性数据中确认这一行为。
在以下情况下,您可能仍需要真正的本地 HTTPS:
- 您正在测试与生产环境匹配的 Cookie 行为,特别是在非 localhost 主机名上使用
SecureCookie - 您正在测试 OAuth 或 OIDC 流程,回调 URL 必须匹配已注册的 HTTPS 源
- 您正在使用自定义主机名(如
app.localhost)而非localhost进行开发 - 您需要在同一网络上的移动设备上进行测试
- 您的前端和后端都在本地运行,必须通过 HTTPS 通信以复现生产环境行为
如果以上情况都不适用,跳过设置,保持简单即可。
为什么自签名证书效果不佳
最直观的做法是生成自签名证书。问题在于:除非证书由已知的证书颁发机构签名,否则浏览器不会信任它。自签名证书会触发”您的连接不是私密连接”警告,您每次都必须点击通过——或者完全禁用证书验证,这会养成不良习惯。
正确的方法是创建一个本地证书颁发机构,让您的系统和浏览器信任它,然后颁发由该 CA 签名的证书。这正是 mkcert 的作用。
使用 mkcert 设置受信任的本地证书
mkcert 是一个零配置工具,可创建本地 CA、将其注册到系统信任存储,并颁发由其签名的证书。浏览器会信任这些证书而不会发出警告。
步骤 1:安装 mkcert
在 macOS 上:
brew install mkcert
brew install nss # Firefox 需要
在 Linux 上,使用您的包管理器或参考 mkcert 安装指南。在 Windows 上,使用 Chocolatey 或 Scoop。
步骤 2:注册本地 CA
mkcert -install
这会创建一个根 CA 并将其添加到系统的信任存储中。每台机器只需执行一次。
步骤 3:为您的主机名生成证书
mkcert localhost
# 或为自定义主机名:
mkcert app.localhost
这会生成两个文件:证书(.pem)和私钥(-key.pem)。将它们排除在版本控制之外——添加到 .gitignore 中。
Discover how at OpenReplay.com.
配置开发服务器使用 HTTPS
如何将证书传递给开发服务器取决于您使用的工具。
Vite — 最简单的方式,使用 vite-plugin-mkcert:
import mkcert from 'vite-plugin-mkcert'
import { defineConfig } from 'vite'
export default defineConfig({
plugins: [mkcert()]
})
该插件会自动处理证书生成和服务器配置。
Vite(手动方式):
import fs from 'fs'
import { defineConfig } from 'vite'
export default defineConfig({
server: {
https: {
key: fs.readFileSync('./localhost-key.pem'),
cert: fs.readFileSync('./localhost.pem'),
}
}
})
Next.js — 在最新版本中使用 next dev --experimental-https 标志,或使用相同的证书文件手动配置自定义 Node.js HTTPS 服务器。
Node.js(任何框架):
const https = require('https')
const fs = require('fs')
https.createServer({
key: fs.readFileSync('localhost-key.pem'),
cert: fs.readFileSync('localhost.pem'),
}, app).listen(3000)
重要提示: 切勿共享或提交 mkcert 生成的
rootCA-key.pem文件。如果有人获得该文件,他们可以为您机器上的任何域颁发受信任的证书。运行mkcert -CAROOT查找其存储位置。
关于 Node.js 的安全说明
如果您的本地后端向其他本地服务发起 HTTPS 请求,Node.js 不会自动信任您的 mkcert CA——它使用自己内置的受信任颁发机构列表,而非系统信任存储。通过设置环境变量来解决此问题:
export NODE_EXTRA_CA_CERTS="$(mkcert -CAROOT)/rootCA.pem"
将此添加到您的 shell 配置文件(.bashrc、.zshrc 等)中,以便在会话间持久保存。
总结
启用本地 HTTPS 并非每个项目都需要——但当您确实需要时,自签名证书无法胜任。mkcert 可在几分钟内为您提供受信任的 localhost 证书,无需浏览器警告或变通方案。只需设置一次,将开发服务器指向生成的文件,您的本地环境就会与生产环境表现完全一致。
常见问题
在 localhost 上使用 Service Worker 需要 HTTPS 吗?
不需要。所有主流浏览器都将 localhost 视为安全上下文,因此 Service Worker、地理定位 API 和其他安全上下文功能在 localhost 上通过纯 HTTP 即可工作。只有在测试类生产环境的 Cookie 行为、针对 HTTPS 源的 OAuth 回调、使用自定义主机名开发或通过网络在移动设备上测试时,才需要本地 HTTPS。
使用 mkcert 进行本地开发安全吗?
是的,mkcert 用于本地开发是安全的。它创建的证书颁发机构仅受您的机器信任。关键风险在于它生成的 rootCA-key.pem 文件。如果其他人获得该文件,他们可以颁发您的浏览器会信任的证书。切勿将其提交到版本控制,运行 mkcert -CAROOT 检查其存储位置。
为什么即使安装了 mkcert,我的 Node.js 服务器仍拒绝向其他本地服务发起 HTTPS 请求?
Node.js 不使用操作系统的信任存储。它依赖自己内置的证书颁发机构列表,因此不会自动信任您的 mkcert CA。将 NODE_EXTRA_CA_CERTS 环境变量设置为指向您的 mkcert rootCA.pem 文件,并将其添加到 shell 配置文件中,以便在终端会话间持久保存。
除了 Vite 和 Next.js,我可以在其他框架中使用 mkcert 证书吗?
可以。任何接受 TLS 密钥和证书文件的开发服务器或框架都可以使用。使用 mkcert 生成文件,然后将它们传递给服务器配置。Express、Fastify、Webpack Dev Server 等都支持自定义 HTTPS 选项。vite-plugin-mkcert 插件只是为 Vite 项目自动化了这一步骤。
Gain control over your UX
See how users are using your site as if you were sitting next to them, learn and iterate faster with OpenReplay — the open-source session replay tool for developers. Self-host it in minutes, and have complete control over your customer data.
Star on GitHub12k