使用Fetch API以Stream为请求体时遇net::ERR_H2_OR_QUIC_REQUIRED错误求助
解决Fetch流式请求的net::ERR_H2_OR_QUIC_REQUIRED错误
错误原因
使用duplex: 'half'配置的Fetch流式请求,必须依赖HTTP/2或QUIC协议才能工作。你的Node.js服务器如果仍在使用HTTP/1.1,就会触发这个错误——因为HTTP/1.1不支持客户端分批次发送请求体的流式上传能力。
解决方案
1. 给Node.js服务器启用HTTP/2
Node.js原生支持HTTP/2,需要配置服务器使用HTTPS(浏览器环境下HTTP/2通常要求通过TLS运行)。示例代码如下:
const http2 = require('http2'); const fs = require('fs'); // 加载SSL证书(本地开发可使用自签名证书) const server = http2.createSecureServer({ key: fs.readFileSync('server.key'), cert: fs.readFileSync('server.crt') }); server.on('stream', (stream, headers) => { // 处理流式请求数据 let receivedData = ''; stream.on('data', chunk => { receivedData += chunk.toString(); console.log('收到分片数据:', chunk.toString()); }); stream.on('end', () => { console.log('流式请求完成,总数据:', receivedData); stream.respond({ 'content-type': 'text/plain', ':status': 200 }); stream.end('已成功接收流式上传数据'); }); }); server.listen(3000);
2. 生成自签名证书用于本地测试
如果是本地开发场景,可以用OpenSSL快速生成自签名证书:
openssl req -x509 -newkey rsa:2048 -nodes -sha256 -subj '/CN=localhost' \ -keyout server.key -out server.crt
生成后需要在浏览器中手动信任该证书,否则会出现SSL安全提示。
3. 调整客户端请求地址
确保客户端请求的是HTTPS协议地址,比如https://localhost:3000/stream,而非HTTP。
替代方案(无法启用HTTP/2时)
如果暂时无法升级到HTTP/2,可以放弃流式上传,先收集所有数据再一次性发送:
const encoder = new TextEncoder(); const dataChunks = []; // 先收集所有分片数据 await new Promise(resolve => { let i = 0; const intervalId = setInterval(() => { dataChunks.push(encoder.encode(`${i}`)); if (++i === 5) { clearInterval(intervalId); resolve(); } }, 2000); }); // 合并数据后发送 const fullData = new Blob(dataChunks); await fetch('/stream', { method: 'POST', body: fullData, headers: { 'Content-Type': 'text/plain' } });
关键提示
duplex: 'half'是Fetch API实现流式上传的必要配置,但该特性仅在HTTP/2或QUIC协议环境下被浏览器支持。- 生产环境建议使用正规CA颁发的SSL证书,避免自签名证书的安全限制。
内容的提问来源于stack exchange,提问作者Akshit Bansal
相关产品推荐
相关产品推荐

