You need to enable JavaScript to run this app. Express接口错误本该返回JSON却返回HTML导致前端JSON解析报错
优惠活动
大模型
产品
解决方案
定价
更多

Express接口错误本该返回JSON却返回HTML导致前端JSON解析报错

异常根因说明

你观察到的「响应头Content-Type为text/html、返回内容是带<html><body><pre>标签的默认错误页」,是Express框架内置兜底错误页的典型特征。出现这个问题的核心原因是:你写的用来返回JSON的全局错误处理中间件,根本没有被执行到,请求抛出业务错误后直接落到了Express默认的HTML错误返回逻辑上。
结合你提到的「此前服务运行正常、近期突然出现异常」的背景,按出现概率从高到低,常见的触发原因有三个:

  • 中间件挂载顺序错误
    Express的中间件严格按照代码书写的从上到下顺序匹配执行,带4个参数(error, req, res, next)的全局错误处理中间件,必须放在所有业务路由、普通中间件的最后面挂载。如果近期调整代码时,把错误处理中间件挪到了路由注册逻辑的前面,抛出的错误会直接绕过这个自定义逻辑,落到框架默认兜底。
  • 被前端SPA适配逻辑拦截
    前后端分离项目通常会加一段匹配所有路径的兜底逻辑,用来解决前端history路由刷新404的问题(比如用app.get('*', (req, res) => res.sendFile('index.html'))让所有非接口请求返回前端页面)。这类逻辑都是不带错误参数的普通中间件,如果这段代码放在了全局错误处理中间件的前面,哪怕是接口请求抛出错误,也会先被这个返回HTML的逻辑接住,根本走不到后面的JSON返回逻辑——这也是很多项目原本正常、加完SPA路由适配后突然出现接口返回HTML问题的最常见踩坑点。
  • 自定义错误中间件未被成功注册
    比如修改错误中间件代码时,漏写了app.use(...)的注册调用,或者这段注册逻辑被if条件判断包裹,实际运行时根本没有执行到注册流程。
排查&解决方案
  1. 先验证中间件的执行状态
    你已经在自定义错误中间件里加了console.log('error middleware: ' + error)的日志,现在触发一次密码错误的登录请求,观察服务端控制台的输出:
  • 如果完全没有打出这行日志:100%是中间件挂载顺序错误。按照「先注册所有业务路由→再注册静态资源、SPA页面兜底逻辑→最后注册全局错误处理中间件」的顺序调整代码,参考结构:
    // 第一步:注册所有业务接口路由
    app.use('/auth', authRouter)
    app.use('/api', apiRouter)
    
    // 第二步:注册静态资源、前端SPA路由兜底
    app.use(express.static('public'))
    app.get('*', (req, res) => res.sendFile(path.join(__dirname, 'public/index.html')))
    
    // 第三步:必须在代码最后面注册全局错误处理中间件
    app.use((error, req, res, next) => {
        const message = error.message;
        const status = error.statusCode || 500;
        const data = error.data;
        // 手动设置响应头,强制走JSON返回,避免被框架默认逻辑覆盖
        res.setHeader('Content-Type', 'application/json')
        res.status(status).json({ message, data });
    })
    
  1. 如果日志正常打出,但仍然返回HTML内容
    检查错误中间件内部的执行流程:确认在调用res.status(status).json(...)之前,没有其他代码提前触发过res.send()、res.render()、res.redirect()等会主动结束响应的逻辑,导致JSON返回代码被中断。
  2. 针对前端抛出的SyntaxError: Unexpected token < in JSON at position 0报错
    这个报错不需要调整前端代码,本质是后端返回的HTML字符串第一个字符是<,前端调用res.json()解析时自然会抛出语法错误。等后端的返回逻辑修正为JSON格式后,这个报错会自动消失。

调整完成后可以通过浏览器网络面板检查登录请求的响应头,确认Content-Type为application/json、响应内容是结构化JSON数据,即为修复完成。

内容的提问来源于stack exchange,提问作者msorr95

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.11.02 14:27:05