You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

MEAN应用中GET API返回HTML而非JSON的问题排查

问题原因及解决方案

核心问题:路由与中间件顺序错误 + 模型缺失

你的请求返回HTML而非JSON,主要由两个关键问题导致:

1. 中间件与路由顺序颠倒

在server.ts中,CORS、响应头配置等中间件被放在了所有路由之后,同时Angular Universal的通配路由app.get('*', ...)虽然在API路由之后,但如果API请求处理出错,会直接触发通配路由返回HTML页面。更关键的是,这些核心中间件根本不会被API请求执行,因为路由已经提前返回了响应。

2. Controller未导入Mongoose模型

farmerController中使用了Farmer.find(),但没有导入对应的Farmer模型,运行时会抛出错误,最终请求被通配路由拦截,返回HTML。


修复步骤

1. 调整中间件与路由顺序

将中间件配置移到所有路由之前,确保所有请求都经过CORS、JSON解析等处理:

import 'zone.js/node';
const mongoose = require('mongoose');
const express = require('express');
const cors = require("cors");

import { APP_BASE_HREF } from '@angular/common';
import { ngExpressEngine } from '@nguniversal/express-engine';
import { existsSync } from 'fs';
import { join } from 'path';
import { AppServerModule } from './src/main.server';

const dotenv = require('dotenv');
const app = express();
dotenv.config({path: './config.env'});
const farmerRoute = require('./routes/farmerRoute');
const bodyParser = require('body-parser');

// 先配置核心中间件
app.use(function(req, res, next) {
    res.header("Access-Control-Allow-Origin", "*");
    res.header("Accept", "application/json");
    res.header("Content-Type", "application/json");
    res.header("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept");
   next();
});

const corsOptions = {
    "origin": "*",
    "methods": "GET,HEAD,PUT,PATCH,POST,DELETE",
    "preflightContinue": false,
    "optionsSuccessStatus": 204
}
app.use(cors(corsOptions));

app.use(express.json()); // 移除重复的bodyParser.json(),两者功能一致

// 连接数据库
const db = process.env.DATABASE.replace('<PASSWORD>', process.env.DATABASE_PASSWORD);
mongoose.connect(db, {
    useNewUrlParser:true,
    useCreateIndex:true,
    useFindAndModify:false
}).then(con => {
    console.log('DB connection successful')
})

// 注册API路由
app.use('/api', farmerRoute);

// 最后配置Angular Universal相关路由
const distFolder = join(process.cwd(), 'dist/farmer-world/browser');
const indexHtml = existsSync(join(distFolder, 'index.original.html')) ? 'index.original.html' : 'index';

app.engine('html', ngExpressEngine({
bootstrap: AppServerModule,
}));

app.set('view engine', 'html');
app.set('views', distFolder);

app.get('*.*', express.static(distFolder, {
maxAge: '1y'
}));

app.get('*', (req, res) => {
res.render(indexHtml, { req, providers: [{ provide: APP_BASE_HREF, useValue: req.baseUrl }] });
});

const port = process.env.port || 3000;
app.listen(port, () => {
    console.log(`app is running on ${port}`);
})

2. 补全Controller的模型导入

在farmerController文件顶部导入Farmer模型(根据你的实际模型路径调整):

const Farmer = require('./../models/farmerModel'); // 替换为你的模型文件路径

exports.getAllFarmers = async (req, res) => {
    try {
        const farmers = await Farmer.find();
        
        return res.status(200).json({
            status: 'success',
            data: farmers
        })
    } catch (err) {
        return res.status(400).json({
            status:'fail',
            message: err.message // 建议返回错误文本而非整个错误对象
        })
    }
}

3. 添加全局错误处理(可选)

添加全局错误中间件,确保所有错误都返回JSON格式,避免请求落到通配路由:

// 放在所有路由之后
app.use((err, req, res, next) => {
    err.statusCode = err.statusCode || 500;
    err.status = err.status || 'error';

    res.status(err.statusCode).json({
        status: err.status,
        message: err.message
    });
});

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.07 21:10:28