配置了Nginx HTTP/2但浏览器还是显示HTTP/1.1?
折腾了一下午配置Nginx的HTTP/2,按照教程设置了443端口和ssl参数,但Chrome开发者工具里网络请求还是显示协议HTTP/1.1。我用JavaScript检测协议的代码也没反应,是不是哪里漏了?
fetch('/api/check')
.then(response => {
console.log('Protocol:', response.headers.get('Via') || 'HTTP/1.1');
});
我的Nginx配置用了server块里的
listen 443 ssl http2;
,证书也验证通过了。重启服务后curl –http2测试也没报错,但前端代码始终得不到HTTP/2的标识…
你用
Via头检测是完全错误的,HTTP/2 根本不会加这个头。正确的方式是用 Performance API:然后说回为什么浏览器还是显示 HTTP/1.1,有几个可能:
1. Nginx 版本太旧
HTTP/2 需要 Nginx 1.9.5+,用
nginx -v确认一下。2. OpenSSL 不支持 ALPN
这是最常见的原因。HTTP/2 依赖 ALPN 握手,你得确认 OpenSSL 版本:
需要 OpenSSL 1.0.2 及以上才行。很多 CentOS 6/7 的默认源更新后还是旧版。
3. Chrome 自己的问题
打开
chrome://net-internals/#http2,看看浏览器认为当前连接状态是什么。如果显示 "HTTP/2 session" 列表为空,说明浏览器根本没走 HTTP/2。4. 配置检查
确认你的配置是这种形式:
如果上面都确认没问题,但 DevTools 的 Protocol 列还是显示 HTTP/1.1——那可能是你看错了列,或者刷新方式不对。试试清空缓存后硬刷新(Ctrl+Shift+R)。
先跑一下
nginx -V 2>&1 | grep -o http2看看编译时有没有带 HTTP/2 模块。首先,
response.headers.get('Via')并不是一个标准的HTTP/2检测方式,很多服务器不会返回这个头。更靠谱的做法是直接用浏览器的开发者工具看“协议”那一栏,或者通过fetch检查:protocol伪头(不过目前主流浏览器还不支持直接获取这个值)。其次,你的Nginx配置看起来没问题,但如果浏览器还是显示HTTP/1.1,可能是以下几个原因:
1. 客户端不支持ALPN(应用层协议协商),这是HTTP/2的关键依赖。
2. 中间有代理或CDN拦截了请求,降级成了HTTP/1.1。
3. 浏览器缓存导致看到的是旧结果。
这里给你一个更优雅的检测方法,直接在页面上加个简单的脚本:
另外,建议你试试用
openssl s_client -connect yourdomain.com:443 -nextprotoneg ""来验证ALPN是否正常工作。如果输出里有h2,说明你的Nginx已经成功启用HTTP/2了。最后再提醒一下,如果用了CDN(比如Cloudflare),记得检查它的设置是否强制启用了HTTP/2。有时候问题出在CDN而不是Nginx本身。
希望这能帮你解决问题!