引言
排查问题像断案,报错信息是非常重要的断案线索。然而有时候你把报错信息当做指路明灯,结果它却把你戏耍一番。比如报"文件不存在",实际原因是你权限不够;比较报"跨域了",真实原因是后端服务启动出了故障。你以为它每次提供的信息很可靠,其实它有时也不靠谱。
本文就来盘一盘这些看起来一本正经、实则胡说八道的报错,揭开这些报错的根本原因。
1. 明明是 404,浏览器却报跨域
- 表面错误 :
No 'Access-Control-Allow-Origin' header present.
- 实际原因 :
请求的接口并不存在,服务未启动或路径拼错,Nginx 返回的是默认的 404 HTML 页面。由于这个 HTML 响应中没有任何 CORS 相关头信息,浏览器认为是 CORS 错误。 - 示例 :
你请求http://api.example.com/data
,而服务器未部署/data
路由。Nginx 返回一个 HTML 错误页,浏览器看到没有Access-Control-Allow-Origin
头,就拦截了响应。 - 建议排查 :
用 Postman 或 curl 请求接口,查看是否返回了 HTML 错误页而不是预期的 JSON 数据。
2. 明明文件存在,却报文件不存在
-
报错信息 :
error: cannot spawn .husky/prepare-commit-msg: No such file or directory
-
实际原因 :
文件确实存在,但缺少执行权限(在 Linux 上未设置
chmod +x
)。对于 Git hooks 来说,脚本必须具有可执行权限。 -
解决方法:
bashchmod +x .husky/prepare-commit-msg
3. HTTPS 请求被拦截,却报连接超时
-
报错信息 :
ERR_CONNECTION_TIMED_OUT
或NetworkError
-
真实原因 :
请求在 TLS 握手阶段被拦截(如中间人攻击、代理拦截、证书伪造),而不是目标服务器未响应。因为握手失败,浏览器感知不到是 HTTPS 错误,只能报"超时"。
-
排查方式 :
用 curl 带
-v
参数,能看到是否 SSL 握手失败。比如:bashcurl -v https://api.example.com
4. 明明是路径写错了,却报变量 ReferenceError
-
报错信息 :
ReferenceError: myVar is not defined
-
真实原因:
你在构建时(例如使用 Webpack/Vite)使用了错误的路径大小写
你的变量在config.js中定义:
js
// config.js
export const myVar = 'hello';
在main.js中正常导入
js
// main.js
import { myVar } from './config'; // ✅ 合法路径,不会报错
console.log(myVar);
可是你如果不小心误写成这样:
js
import { myVar } from './Config'; // ❌ 注意 C 是大写
-
在 Windows 和 macOS 上,文件系统是大小写不敏感的,这段代码能运行并构建成功,但在 Linux(例如部署到服务器)上就会报
ReferenceError: myVar is not defined
或找不到模块。 -
为什么报 ReferenceError,而不是模块加载失败?
因为某些构建工具(如 Webpack)处理路径缓存或构建优化时,可能错误解析到了一个空模块,导致后续变量没被定义,表现为
ReferenceError
而不是Module not found
。
5. 请求的是 JSON,结果却 JSON.parse 失败
- 报错信息 :
SyntaxError: Unexpected token '<'
- 真实原因 :
接口返回的不是 JSON,而是 HTML 报错页面(如 404、500 页面)。<
是 HTML 的起始标签,导致 JSON.parse 失败。 - 排查方式 :
打印response.text()
内容看返回内容,而不是直接用response.json()
。
6. 密码明明正确,数据库连接失败却提示"密码错误
-
报错 :
FATAL: password authentication failed for user "myuser"
-
可能原因:
- 数据库服务未启动
- 防火墙屏蔽端口
- 客户端连接请求根本未到数据库
- 用户 IP 未加入数据库白名单
-
排查建议:
bashtelnet db.example.com 5432
或使用
nc
查看端口可用性:bashnc -zv db.example.com 5432
7. npm ERR! code ELIFECYCLE 报错难定位
-
常见输出:
bashnpm ERR! code ELIFECYCLE npm ERR! errno 1 npm ERR! [email protected] start: `node app.js`
-
真实原因 :
node app.js
本身执行失败,可能由于:- 文件语法错误
- 缺少依赖
- 环境变量未设置
- 权限不足
- 端口被占用
-
解决方式 :
加上
--verbose
输出详细日志:bashnpm run start --verbose
8. git show 报 HEAD detached 让人困惑
-
提示 :
HEAD detached at abc1234
-
实际含义 :
当前不在任何分支,而是 checkout 到了一个具体提交或 tag。
-
常见操作导致此状态:
bashgit checkout abc1234
-
解决方式 :
如果想在当前状态上继续开发并保留历史,可创建新分支:
bashgit checkout -b new-feature
9. HTTPS 页面却报 Mixed Content 警告
-
提示:
jsMixed Content: The page at 'https://example.com' was loaded over HTTPS, but requested an insecure resource 'http://api.example.com/data'.
-
真实原因:
- 页面是 HTTPS 的,但接口是 HTTP 的
- 或者 Nginx 未传递
X-Forwarded-Proto
,导致后端生成了 HTTP 的 URL
-
解决方案:
- 使用 HTTPS 接口地址
- 后端根据协议头判断是否需要生成 HTTPS 资源链接
10. POST 请求报 Method Not Allowed (405)
-
真实情况 :
跨域请求触发了预检(OPTIONS),但后端未处理该方法或响应缺少 CORS 头。
-
CORS 预检流程简述:
-
浏览器发出 OPTIONS 请求
-
服务器需响应:
jsAccess-Control-Allow-Origin: http://localhost:3000 Access-Control-Allow-Methods: POST, OPTIONS Access-Control-Allow-Headers: Content-Type
-
-
解决方法 :
后端显式处理
OPTIONS
请求,返回 200 + 正确头信息。
11. Vue 项目报 Cannot find module 'vue-template-compiler'
-
真实原因 :
Vue 2 项目中,
vue-template-compiler
版本必须与vue
完全一致。 -
解决方法:
bashnpm install [email protected] [email protected]
Vue 3 不再使用该模块,而是
@vue/compiler-sfc
12. 本地环境报 ERR_CERT_AUTHORITY_INVALID,线上却正常
-
提示 :
NET::ERR_CERT_AUTHORITY_INVALID
-
真实原因 :
本地环境或公司代理注入了自己的证书,用于拦截 HTTPS 流量进行审查。浏览器无法验证这个自签名证书。
-
解决方式:
- 临时信任该证书(如通过系统导入)
- 或绕过代理访问
- 或让 IT 部门导出可信的根证书供开发使用
13. 明明pnpm已经安装,却报'MODULE_NOT_FOUND'
- 报错信息:
bash
Now using node v18.20.6
pnpm already installed
node:internal/modules/cjs/loader:1143
throw err;
^
Error: Cannot find module '../dist/pnpm.cjs'
Require stack:
- /home/jenkins/.nvm/versions/node/v18.20.6/bin/pnpm
at Module._resolveFilename (node:internal/modules/cjs/loader:1140:15)
at Module._load (node:internal/modules/cjs/loader:981:27)
at Module.require (node:internal/modules/cjs/loader:1231:19)
at require (node:internal/modules/helpers:177:18)
at Object.<anonymous> (/home/jenkins/.nvm/versions/node/v18.20.6/bin/pnpm:25:1)
at Module._compile (node:internal/modules/cjs/loader:1364:14)
at Module._extensions..js (node:internal/modules/cjs/loader:1422:10)
at Module.load (node:internal/modules/cjs/loader:1203:32)
at Module._load (node:internal/modules/cjs/loader:1019:12)
at Function.executeUserEntryPoint [as runMain] (node:internal/modules/run_main:128:12) {
code: 'MODULE_NOT_FOUND',
requireStack: [ '/home/jenkins/.nvm/versions/node/v18.20.6/bin/pnpm' ]
}
- 真实原因: pnpm工具包虽然存在,也有执行权限,因为下列原因:
1)手动移动或覆盖了 /home/jenkins/.nvm/versions/node/v18.20.6/bin/pnpm
或相关路径
2)CI 缓存污染(比如 Jenkins 的工作区残留旧文件)
3)nvm install
过程中中断或失败
造成pnpm损坏,文件存在,却无法正确运行。
总结
程序员和报错信息的关系,有时候就像是在猜哑谜。你以为它说"文件不存在",其实它是"你没权限";你以为它说"跨域了",其实是"服务根本没起来"。你习惯了它有话直说,可是它有时候会忽悠你,把人带偏,浪费大量时间在错误的地方打转。
所以,不可全信报错的字面意思,多一分怀疑,多一步验证,可能你就会少绕一些弯路。希望本文盘点的典型误导报错能帮你避开一些常见陷阱,少动一些肝火,少做一点无用功,早一点下班。