如何解决 Vue2 前端项目为何无法访问本地资源(chunk.js 加载一直 pending/转圈)

#VibeCoding·九月创作之星挑战赛#

网罗开发 (小红书、快手、视频号同名)

  大家好,我是 展菲,目前在上市企业从事人工智能项目研发管理工作,平时热衷于分享各种编程领域的软硬技能知识以及前沿技术,包括iOS、前端、Harmony OS、Java、Python等方向。在移动端开发、鸿蒙开发、物联网、嵌入式、云原生、开源等领域有深厚造诣。

图书作者:《ESP32-C3 物联网工程开发实战》
图书作者:《SwiftUI 入门,进阶与实战》
超级个体:COC上海社区主理人
特约讲师:大学讲师,谷歌亚马逊分享嘉宾
科技博主:华为HDE/HDG

我的博客内容涵盖广泛,主要分享技术教程、Bug解决方案、开发工具使用、前沿科技资讯、产品评测与使用体验。我特别关注云服务产品评测、AI 产品对比、开发板性能测试以及技术报告,同时也会提供产品优缺点分析、横向对比,并分享技术沙龙与行业大会的参会体验。我的目标是为读者提供有深度、有实用价值的技术洞察与分析。

展菲:您的前沿技术领航员
👋 大家好,我是展菲!
📱 全网搜索“展菲”,即可纵览我在各大平台的知识足迹。
📣 公众号“Swift社区”,每周定时推送干货满满的技术长文,从新兴框架的剖析到运维实战的复盘,助您技术进阶之路畅通无阻。
💬 微信端添加好友“fzhanfei”,与我直接交流,不管是项目瓶颈的求助,还是行业趋势的探讨,随时畅所欲言。
📅 最新动态:2025 年 3 月 17 日
快来加入技术社区,一起挖掘技术的无限潜能,携手迈向数字化新征程!


前言

最近遇到不少同学反馈:Vue2 项目能 npm run serve 启动,但页面一直转圈,某个 chunk.js 加载不到(pending),静态 logo 却能显示,别人能 ping 通你的电脑但访问端口就不通。本篇把这类问题做成一篇易读的技术文章,按排查思路一步步来,最后给出可运行的 Demo 与常见修复方法。

摘要

浏览器能 ping 主机但无法加载某个 chunk,常见原因并非“Vue 框架坏了”,而是 本机服务监听/网络路径/代理/防火墙/host/DNS/webpack publicPath 等网络层面或环境配置的问题。重点排查:dev server 的绑定地址(host)、chunk 的 URL(publicPath)、本机防火墙或企业代理/安全网关、以及环境变量(HTTP_PROXY/NO_PROXY)。

先看现象

  • Vue2(element + 公司封装库),npm i; npm run serve 启动没报错。
  • 浏览器打开页面:公司 logo(静态资源)能加载,但项目的某个 chunk.js 一直 pending(转圈)。
  • 今天上午正常,下午就不行了(环境突然变坏)。
  • 任务管理器无异常;公司安全软件怀疑但被排查为“没问题”。
  • 在本机上其他人的项目也出现相同现象(说明环境问题)。
  • 别人的电脑能 ping 到你机器,但访问端口(例如 8080)就一直转圈。
  • 切换浏览器/无痕都不行。Node 版本受限(公司要求 node 14.18.0)。

为什么会发生?可能的原因一览

  1. dev server 只绑定到 127.0.0.1(localhost)而不是 0.0.0.0,外网访问或用其他主机名会失败(但 ping 主机仍然能通,因为 ICMP 与 TCP 端口不同)。
  2. 本机防火墙或安全产品阻止了 TCP 端口(允许 ping,但拦截 TCP/HTTP)。
  3. webpack devServer 的 publicPath / BASE_URL 配置错误,chunk 的实际 URL 指向错误域名或端口。
  4. 本地代理 / HTTP_PROXY / HTTPS_PROXY 环境变量影响,导致请求被代理或中断。
  5. **企业安全/网关(WAF、IDS/IPS、证书中间人)**阻止对某些文件扩展名或大文件传输。
  6. 端口被占用 / 启动了不同实例 / 启动出错但未明显报错(例如 HMR 服务没有启动但静态文件有)。
  7. 浏览器缓存 / Service Worker / PWA 的缓存策略导致旧资源或错误地址被请求。
  8. DNS/hosts 被改动(本机或公司内网 DNS 指向错误)导致 chunk 请求去到不可达服务。
  9. webpack/打包链路出错,chunk 未生成或路径名发生变化(不太常见,但要确认文件存在)。

排查步骤

下面是一个实战化的排查流程,照着做,能一步步把问题逼近并修复。

1) 在浏览器 DevTools 查看 Network

  • 打开 Network 面板,刷新页面。

  • 找到那个 pending 的 chunk.js,右键 → Open in new tab,观察地址(完整 URL)、协议(http/https)、端口、host。

  • 观察返回状态:pending / stalled / blocked:other / net::ERR_CONNECTION_REFUSED / net::ERR_CONNECTION_TIMED_OUT / CORS 报错等。

    • ERR_CONNECTION_REFUSED:说明目标主机没有在该端口监听(或被本机防火墙拦截)。
    • ERR_CONNECTION_TIMED_OUT:网络路由被丢弃,可能被防火墙或代理中间件阻断。
    • blocked:浏览器或扩展拦截。
  • 如果请求 URL 指向 http://localhost:8080/...,且在同机器上打开仍 pending,则问题在本机(服务或防火墙)。

  • 如果 URL 指向 http://your-hostname:8080/...,但你的 dev server 只绑定 localhost,外网访问会失败。

2) 在启动终端看 npm run serve 输出

Vue CLI / webpack-dev-server 启动时会打印:

App running at:
- Local:   http://localhost:8080/
- Network: http://192.168.x.y:8080/

确认 Network 地址是否展示且端口正确。若没有显示 Network 地址,说明绑定了 127.0.0.1

3) 检查服务监听地址(端口绑定)

在终端运行(不同系统命令):

  • Linux/macOS:
# 查看 8080 是否被进程监听(替换端口)
ss -tlnp | grep 8080
# 或
lsof -i :8080
  • Windows (PowerShell):
netstat -ano | findstr :8080
# 得到 PID 后: tasklist /FI "PID eq 1234"

解释:如果监听地址是 127.0.0.1:8080,外网访问会失败;若是 0.0.0.0:8080,表示所有网卡都绑定了。

4) 用 curl / telnet / nc 测试

  • 在本机(Server)试:
curl -v 'http://localhost:8080/path/to/chunk.js'
  • 在局域网另一台电脑试(用你的 IP):
curl -v 'http://192.168.x.y:8080/path/to/chunk.js'
# 或
telnet 192.168.x.y 8080
# 或 nc -vz 192.168.x.y 8080

如果 curl 在本机能成功但远程失败,说明防火墙或路由问题。重要:ping 通不代表 TCP 端口可达(ICMP vs TCP)。

5) 检查防火墙/安全软件

  • Windows 防火墙:可以短暂禁用防火墙测试(仅限调试),或者新建入站规则允许该端口。

    • 关掉测试(慎重):

      # 仅测试时运行(管理员)
      netsh advfirewall set allprofiles state off
      # 开启
      netsh advfirewall set allprofiles state on
      
  • Linux ufw

sudo ufw status
sudo ufw disable   # 仅测试
sudo ufw enable
  • macOS:

    • 去 系统偏好设置 → 安全性与隐私 → 防火墙,临时关闭测试。
      注意:企业安全软件可能不会被这些操作影响(它是在驱动层或网卡层拦截)。与安全团队沟通,让他们查看是否有端口策略或流量审计。

6) 检查代理环境变量

有些公司环境会设置 HTTP_PROXY HTTPS_PROXY,会影响 npmcurl 等。查看环境变量:

# macOS / Linux
env | grep -i proxy

# Windows PowerShell
Get-ChildItem Env:*proxy*

如果有代理,确保你添加 NO_PROXY 列表包含本地地址和局域网 NO_PROXY=localhost,127.0.0.1,192.168.0.0/16

7) 检查 webpack/vite/publicPath 配置

如果 chunk 的 URL 指向了错误域名(比如使用机器名、或者使用了 HTTPS 协议但 dev server 是 HTTP),会导致请求卡住。检查 vue.config.js

// vue.config.js
module.exports = {
  publicPath: '/', // 或者你项目需要的 base url
  devServer: {
    host: '0.0.0.0', // 允许外网访问
    port: 8080,
    allowedHosts: 'all', // webpack-dev-server 4+
    // disableHostCheck: true (旧版本)
  }
}

如果你用的是 --host 参数,也可以:

# 允许外网访问并把地址打印为 Network
HOST=0.0.0.0 npm run serve
# 或
npm run serve -- --host 0.0.0.0

保证 dev server 绑定到 0.0.0.0,而不是 localhost

8) 清理缓存、重装依赖

rm -rf node_modules package-lock.json yarn.lock
npm cache clean --force
npm install
npm run serve

有时公司内部私服(npm registry)或者缓存损坏也会导致构建产物不完整。

9) 检查浏览器安全插件 / Service Worker

  • 试一个完全干净的浏览器(新装或 Profile),或手机热点网络。
  • 如果有 Service Worker 或 PWA,清除站点数据 + unregister SW(DevTools → Application → Service Workers)。

10) 用端口转发/外网隧道验证

如果怀疑公司网络设备拦截,临时用 ngrok / localtunnel 将本地服务公开到外网(仅测试):

npm i -g localtunnel
lt --port 8080
# or ngrok http 8080

如果通过隧道访问正常,说明确实被公司网络/防火墙拦截。

常见根因 & 对应的解决办法

根因 A:devServer 只监听 localhost

症状:本机浏览器访问 localhost 正常,但别人或通过 IP 访问或跨网卡访问失败。
解决:在 vue.config.js 或命令行里把 host 改为 0.0.0.0

// vue.config.js
module.exports = {
  devServer: { host: '0.0.0.0', port: 8080, allowedHosts: 'all' }
};

或者:

npm run serve -- --host 0.0.0.0

根因 B:本机/企业防火墙拦截该端口

症状:ping 能通但 curl 远程访问超时或被拒。
解决:与安全团队沟通,临时允许某端口;或自行临时关闭防火墙排查(仅限测试)。

根因 C:环境代理(HTTP_PROXY/HTTPS_PROXY)影响

症状:请求被公司代理篡改或转发失败。
解决:设置 NO_PROXY=localhost,127.0.0.1,192.168.0.0/16,或在 DevServer 配置绕过代理。

根因 D:wrong publicPath / chunk URL 指向不对

症状:Network 里显示请求去往错误域名或协议。
解决:修 publicPath(Vue CLI)或 base(Vite),确保静态资源 URL 与 dev server 的 host/port 对应。

根因 E:HMR/socket 升级失败(导致页面卡住)

症状:控制台显示 HMR websocket 连接失败,页面不加载最新 chunk。
解决:使 HMR 可从浏览器访问,devServer.hot = true,并确保 sockjs 路径正确或 public 指向正确域名。

根因 F:安全/审计软件做了中间人或 TLS 检查

症状:HTTPS 证书异常或加载被 reset,通常在公司网络。
解决:检查浏览器 security tab,若证书由公司 CA 签发则与安全团队确认规则是否拦截 JS 文件。

可运行 Demo

下面的 Demo 非常小:一个 Express 静态服务器,分别在 127.0.0.10.0.0.0 启动,演示如何用 curl 在本机和远程测试访问。把代码复制到目录,运行体验。

server.js

// server.js
const express = require('express');
const app = express();
app.use(express.static(__dirname + '/public'));

app.get('/ping', (req, res) => res.send('pong'));
const port = process.env.PORT || 8080;

const host = process.env.HOST || '127.0.0.1'; // 默认只监听本地
app.listen(port, host, () => {
  console.log(`Static server running at http://${host}:${port}/`);
});

public/index.html

<!doctype html>
<html>
<head><meta charset="utf-8"><title>Static Demo</title></head>
<body>
  <h1>Hello static</h1>
  <script src="/js/chunk-demo.js"></script>
</body>
</html>

public/js/chunk-demo.js

console.log('chunk-demo loaded');

运行步骤

  1. 安装并运行(本地):
npm init -y
npm i express
node server.js        # 默认绑定 127.0.0.1
# 在浏览器打开 http://localhost:8080/ 应该能看到页面。
  1. 在另一台机器(或用本机用 IP)测试:
curl -v http://192.168.x.y:8080/  # 如果绑定127.0.0.1,这会失败
  1. 改为绑定 0.0.0.0(允许外网访问)并重启:
HOST=0.0.0.0 node server.js
# 在控制台会看到 Static server running at http://0.0.0.0:8080/
# 这时 curl 访问 http://192.168.x.y:8080/ 应该能成功(如果防火墙未阻拦)

这个 Demo 能直观验证“绑定地址 vs 防火墙”问题:若绑定 127.0.0.1,外网无法访问;若绑定 0.0.0.0 且防火墙允许,则外网能访问。

最终建议

  1. 开发时固定 devServer 配置:在 vue.config.js 里统一 host: '0.0.0.0'allowedHosts: 'all',并文档化团队使用方式(尤其多机器协作时)。
  2. 配置 NO_PROXY:在公司网络环境下,确保 NO_PROXY 覆盖本地和局域网地址。
  3. 把 publicPath 写清楚:避免打包后资源 URL 指向错误域名。
  4. 与安全团队建立沟通渠道:公司安全软件/代理经常是问题来源,建议做一次“允许端口/规则清单”沟通。
  5. 本地调试时使用 ngrok/localtunnel 做快速排查:如果通过隧道能访问,说明是网络/防火墙问题而不是应用问题。
  6. 把常用诊断命令写进 READMEss/netstat/lsof/curl 等快速检查步骤可以节省很多 time-to-fix。

总结

  • ping 能通不等于 HTTP/TCP 端口可达;优先检查 devServer 的 host 绑定与防火墙规则。
  • 用浏览器 DevTools → Network 找到 chunk 的完整 URL,是定位问题最直接的线索。
  • 如果本机环境忽然在一段时间内全部项目都失效,强概率是系统环境(防火墙/代理/hosts/证书)突然变了。
  • 临时用 HOST=0.0.0.0 npm run serveNGROK/LOCALTUNNELcurl -v、关闭防火墙(仅测试)等方式快速定位。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

网罗开发

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值