SvelteKit配置HTTPS连接时出现:method无效请求头错误
问题:HTTPS模式下SvelteKit连接Express服务器报错
Headers.append: ":method" is an invalid header name 环境信息
- Node.js 版本:v20.10.0
- SvelteKit:最新版本
服务器与配置代码
1. Express HTTPS服务器代码
const https = require('https') const key = fs.readFileSync('./cert/key.pem') const cert = fs.readFileSync('./cert/cert.pem') const server = https.createServer({key: key, cert: cert}, app)
2. Vite配置(vite.config.js)
export default defineConfig({ plugins: [sveltekit()], server: { https: { key: fs.readFileSync(`${__dirname}/../server/cert/key.pem`), cert: fs.readFileSync(`${__dirname}/../server/cert/cert.pem`) } } });
错误信息
访问https://localhost:5173时触发以下错误:
TypeError: Headers.append: ":method" is an invalid header name. at webidl.errors.exception (node:internal/deps/undici/undici:1635:14) at webidl.errors.invalidArgument (node:internal/deps/undici/undici:1646:28) at appendHeader (node:internal/deps/undici/undici:2052:29) at fill (node:internal/deps/undici/undici:2038:11) at new Request (node:internal/deps/undici/undici:6151:13) at getRequest (file:///Users/jackgoodman/Desktop/pbbg/client/node_modules/@sveltejs/kit/src/exports/node/index.js:101:9) at file:///Users/jackgoodman/Desktop/pbbg/client/node_modules/@sveltejs/kit/src/exports/vite/dev/index.js:475:27 at process.processTicksAndRejections (node:internal/process/task_queues:95:5)
补充信息
- 切换回HTTP模式后问题消失
- 定位到SvelteKit源码中相关代码(
node_modules/@sveltejs/kit/src/exports/node/index.js),但不知如何处理:
export async function getRequest({ request, base, bodySizeLimit }) { return new Request(base + request.url, { // @ts-expect-error duplex: 'half', method: request.method, headers: /** @type {Record<string, string>} */ (request.headers), body: get_raw_body(request, bodySizeLimit) }); }
解决方案
这个错误的核心原因是:HTTPS模式下,Node.js底层依赖的undici库对请求头校验更严格,不允许:method这类以冒号开头的伪头字段出现在常规请求头中。而SvelteKit的getRequest函数直接把Node.js原生请求的headers对象传给了Request构造函数,原生HTTPS请求的headers对象会包含这些伪头字段,从而触发报错。
临时修复(修改源码)
直接修改找到的SvelteKit源码,在传递headers前过滤掉以:开头的字段:
export async function getRequest({ request, base, bodySizeLimit }) { // 过滤冒号开头的伪头字段 const filteredHeaders = Object.fromEntries( Object.entries(request.headers).filter(([key]) => !key.startsWith(':')) ); return new Request(base + request.url, { // @ts-expect-error duplex: 'half', method: request.method, headers: filteredHeaders, body: get_raw_body(request, bodySizeLimit) }); }
持久化修复(用patch-package)
如果不想每次安装依赖都重新修改源码,可以用patch-package工具保存补丁:
- 安装工具:
npm install patch-package --save-dev - 修改源码后执行:
npx patch-package @sveltejs/kit - 在
package.json的scripts中添加:"postinstall": "patch-package",确保依赖安装后自动应用补丁
替代方案
也可以尝试降级Node.js到v18.x系列,v20.x版本的undici对请求头的校验逻辑更严格,是触发这个问题的诱因之一。
内容的提问来源于stack exchange,提问作者Jack Goodman
相关产品推荐
相关产品推荐

