如何修复 Chrome 中的 ERR_CONNECTION_REFUSED
当 Chrome 显示 ERR_CONNECTION_REFUSED 时,意味着目标服务器主动拒绝了连接请求。与连接超时不同(服务器没有响应),"被拒绝"表示服务器或网络设备明确返回了一个 TCP RST(重置)包,告诉客户端"这个端口没有服务在等待连接"。
这是最常见的前端开发环境错误之一。在本地开发时,通常是因为 Web 服务器未启动或端口不匹配;在生产环境中,则可能是防火墙规则或服务崩溃所致。按照以下 7 个步骤逐一排查即可解决。
步骤 1:检查 Web 服务器是否运行
最常见的原因是 Web 服务器根本没有启动。确认 Nginx、Apache 或开发服务器正在运行:
# Linux: 检查 Nginx
sudo systemctl status nginx
# Linux: 检查 Apache
sudo systemctl status apache2
# Node.js 开发服务器
pm2 status
# 或
ps aux | grep node
# Python 开发服务器
ps aux | grep "python.*manage.py"
如果服务已停止,启动它:
sudo systemctl start nginx
# 或
npm run dev
步骤 2:验证端口是否正确
浏览器默认连接 80 端口(HTTP)或 443 端口(HTTPS),但开发服务器通常使用 3000、8080、4200 等端口。确认您访问的 URL 中的端口号与服务器实际监听的端口一致:
# 确认服务监听的端口
# Nginx 配置中检查 listen 指令
grep -r "listen" /etc/nginx/sites-enabled/
# Node.js 应用启动日志通常会显示端口
# 例如: Server running on port 3000
# 则 URL 应为 http://localhost:3000
常见错误:访问 http://localhost(默认 80 端口)但服务器监听在 8080,或者访问 https://localhost:3000 但开发服务器只支持 HTTP。
步骤 3:检查防火墙规则
防火墙可能配置为 REJECT(拒绝)而非 DROP(丢弃)。REJECT 会立即返回 TCP RST,导致 ERR_CONNECTION_REFUSED;而 DROP 会导致连接超时。检查防火墙状态:
# UFW 防火墙状态
sudo ufw status
# 放行 HTTP 和 HTTPS
sudo ufw allow 80/tcp
sudo ufw allow 443/tcp
# iptables 查看规则
sudo iptables -L -n | grep -E '80|443|3000'
# firewalld (CentOS/RHEL)
sudo firewall-cmd --list-ports
确保防火墙规则中没有将目标端口设置为 REJECT。如果使用云服务器,同时检查云平台的安全组规则。
步骤 4:清除浏览器缓存和 DNS 缓存
浏览器或系统 DNS 缓存可能保存了错误的 IP 或端口映射,导致连接被拒绝。清除缓存:
# Chrome 地址栏输入,清除 DNS 缓存
chrome://net-internals/#dns
# Linux 刷新系统 DNS 缓存
sudo systemctl restart systemd-resolved
# macOS 刷新 DNS 缓存
sudo dscacheutil -flushcache
sudo killall -HUP mDNSResponder
# Windows 刷新 DNS 缓存
ipconfig /flushdns
同时在 Chrome 中尝试隐身模式(Ctrl+Shift+N)访问,排除浏览器扩展和缓存的干扰。
步骤 5:检查代理设置
错误的代理配置会将请求转发到不存在的端口,导致连接被拒绝。检查 Chrome 和系统的代理设置:
# 检查环境变量中的代理设置
echo $http_proxy
echo $https_proxy
echo $no_proxy
# 临时清除代理环境变量
unset http_proxy https_proxy
# Chrome: 设置 > 系统 > 打开代理设置
# 确认"使用代理服务器"已关闭或配置正确
如果您使用 VPN 或代理工具(如 Clash、V2Ray),尝试暂时关闭后重新访问,确认是否是代理导致的连接拒绝。
步骤 6:验证服务是否在监听
即使服务进程在运行,它可能没有绑定到正确的网络接口。例如,服务监听在 127.0.0.1 但您通过外部 IP 访问,或反之。使用 ss 或 netstat 验证:
# 查看所有监听端口
sudo ss -tlnp
# 或使用 netstat
sudo netstat -tlnp
# 关键字段说明:
# LISTEN 0.0.0.0:80 = 监听所有接口的 80 端口
# LISTEN 127.0.0.1:80 = 仅监听本地回环地址
# LISTEN [::]:80 = 监听 IPv6 所有接口
如果服务只监听 127.0.0.1,外部连接将被拒绝。修改配置文件使其监听 0.0.0.0 以接受外部连接:
# Node.js 示例
app.listen(3000, '0.0.0.0');
# Django 示例
python manage.py runserver 0.0.0.0:8000
步骤 7:检查端口冲突
两个服务尝试绑定同一端口时,后启动的服务会失败,导致该端口上只有旧服务或无服务在运行。检查端口占用情况:
# 查看占用特定端口的进程
sudo lsof -i :80
sudo lsof -i :3000
# 或使用 fuser
sudo fuser 80/tcp
# 终止占用端口的进程
sudo kill -9 <PID>
例如,Apache 和 Nginx 同时尝试监听 80 端口,只有一个能成功绑定。确保每个端口只被一个服务使用。对于开发环境,如果 3000 端口被占用,可以换用其他空闲端口如 3001。
快速参考:原因与修复
| 症状 / 日志信息 | 根本原因 | 修复方法 |
|---|---|---|
| 所有网站都无法访问 | 代理设置错误或 VPN 异常 | 关闭代理或 VPN,清除代理环境变量 |
| 仅本地开发服务器被拒绝 | 开发服务器未启动或端口不匹配 | 启动服务器,确认 URL 端口号正确 |
| 远程服务器连接被拒绝 | 服务监听 127.0.0.1 而非 0.0.0.0 | 修改配置绑定到 0.0.0.0 或外部 IP |
| 防火墙规则为 REJECT | 防火墙主动拒绝连接并发送 RST | 将规则改为 ACCEPT 或放行目标端口 |
| 服务启动但端口未监听 | 端口冲突,另一个进程已占用 | 使用 lsof 查找并终止占用进程 |
| 切换网络后无法访问 | DNS 缓存指向旧 IP 或端口 | 刷新系统 DNS 缓存并清除浏览器缓存 |