如何修复 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 访问,或反之。使用 ssnetstat 验证:

# 查看所有监听端口
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 缓存并清除浏览器缓存

相关指南