Express.js服务器Postman请求正常,浏览器访问出现404及连接拒绝错误
问题:浏览器请求Express服务后服务器崩溃,Postman正常运行
我的Express.js服务器代码
const express = require("express"); const app = express(); const axios = require("axios"); const PORT = 3000; var cors = require("cors"); app.use(cors()); app.use(express.json()); require("dotenv").config(); const token = process.env.GitHub_Token; // routes app.get("/:name", (req, res) => { getRepositoryNames(req.params.name).then((repositories) => { getRepositoryLanguages(req.params.name, repositories).then( (languageStats) => { res.send(languageStats); } ); }); }); function getRepositoryNames(username) { return axios .get(`https://api.github.com/users/${username}/repos`, { headers: { Authorization: `token ${token}`, }, }) .then((response) => { return response.data .map((repo) => ({ name: repo.name, })) .map((e) => e.name); }) .catch((error) => { console.log(error); return Promise.reject(error); }); } async function getRepositoryLanguages(owner, repos) { let languageStats = []; for (let index = 0; index < repos.length; index++) { const repoName = repos[index]; const response = await axios.get( `https://api.github.com/repos/${owner}/${repoName}/languages`, { headers: { Authorization: `token ${token}`, }, } ); languageStats.push({ repoName: repoName, languages: response.data, }); } const res = languageStats.reduce( (a, b) => { a.repositories.push(b.repoName); for (const lang of Object.keys(b.languages)) { if (a.languages.hasOwnProperty(lang)) { a.languages[lang] += b.languages[lang]; } else { a.languages[lang] = b.languages[lang]; } } return a; }, { languages: {}, repositories: [] } ); const totBytes = Object.values(res.languages).reduce((a, b) => a + b); for (const lang of Object.keys(res.languages)) { res.languages[lang] = res.languages[lang] / totBytes; } return res; } app.listen(PORT, () => { console.log(`API server listening at http://localhost:${PORT}`); });
问题详情
这段代码仅作演示用,打算部署到Kubernetes,不需要前端,直接用浏览器发GET请求就行。现在用Postman访问localhost:3000/user完全正常,但用Chrome或其他浏览器请求时,虽然能拿到数据,但服务器立刻崩溃,之后会出现404错误和ERR_CONNECTION_REFUSED提示。我怀疑浏览器请求里缺了Postman带的某些请求头,但不知道具体是哪些,也不清楚要给Axios的GET请求加什么头。
排查与修复方案
1. 先补全错误处理,定位崩溃根源
当前代码的Promise链没有全局错误捕获,一旦getRepositoryLanguages调用GitHub API出错,会触发未捕获的Promise拒绝,直接导致服务器崩溃。
修改路由逻辑,改用async/await并添加try/catch:
app.get("/:name", async (req, res) => { try { const repositories = await getRepositoryNames(req.params.name); const languageStats = await getRepositoryLanguages(req.params.name, repositories); res.send(languageStats); } catch (error) { console.error("请求处理失败:", error); // 根据GitHub API的响应返回对应状态码,比如用户不存在返回404 res.status(error.response?.status || 500).send({ error: error.message }); } });
同时给getRepositoryLanguages添加单仓库请求的错误捕获,避免单个仓库出错导致整个流程中断:
async function getRepositoryLanguages(owner, repos) { let languageStats = []; for (let index = 0; index < repos.length; index++) { const repoName = repos[index]; try { const response = await axios.get( `https://api.github.com/repos/${owner}/${repoName}/languages`, { headers: { Authorization: `token ${token}`, }, } ); languageStats.push({ repoName: repoName, languages: response.data, }); } catch (error) { console.error(`获取仓库${repoName}语言信息失败:`, error); // 跳过出错的仓库,继续处理其他仓库 continue; } } // 后续统计逻辑不变 }
2. 统一Axios请求头,匹配浏览器行为
浏览器发起请求时会自动携带User-Agent、Accept等头,Postman默认的头更贴近标准请求,给Axios添加这些头可以避免GitHub API返回非预期响应:
// 定义通用请求头 const commonHeaders = { Authorization: `token ${token}`, "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/118.0.0.0 Safari/537.36", Accept: "application/json" }; // 在getRepositoryNames中使用 axios.get(`https://api.github.com/users/${username}/repos`, { headers: commonHeaders }) // 在getRepositoryLanguages的请求中同样替换headers为commonHeaders
3. 处理浏览器自动发起的额外请求
浏览器访问接口时,会自动请求/favicon.ico,当前代码没有这个路由,会返回404,虽然不会直接导致崩溃,但可以添加默认路由统一处理:
app.get("*", (req, res) => { res.status(404).send("接口不存在"); });
4. Kubernetes部署注意事项
- 确保Pod通过Secret正确挂载
GitHub_Token环境变量 - 服务的端口映射要指向容器的3000端口(NodePort/Ingress配置正确)
- 用
kubectl logs <pod-name>查看Pod日志,获取服务器崩溃的具体报错信息,比本地调试更准确
内容的提问来源于stack exchange,提问作者user346206
相关产品推荐
相关产品推荐

