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

Angular SSR配置Express POST路由失败,请求遭Angular路由拦截

解决Angular 18 SSR中API路由被前端路由接管的问题

核心问题原因

Express路由匹配按顺序执行,若把Angular静态文件服务、SSR路由放在API路由之前,所有请求会先被Angular路由处理,导致/api/login这类请求被判定为前端路由抛出NG04002错误;同时Vite开发环境会将/api路径识别为前端资源路径,进而报错找不到polyfills.js、main.js。

解决方案步骤

1. 调整server.ts的路由顺序

必须让API路由挂载在Angular相关服务之前,确保Express优先处理/api开头的请求:

import { APP_BASE_HREF } from '@angular/common';
import { CommonEngine } from '@angular/ssr';
import express from 'express';
import { fileURLToPath } from 'node:url';
import { dirname, join, resolve } from 'node:path';
import authRoutes from './auth.routes';

const app = express();

const serverDistFolder = dirname(fileURLToPath(import.meta.url));
const browserDistFolder = resolve(serverDistFolder, '../browser');
const indexHtml = join(serverDistFolder, 'index.server.html');

// 1. 先启用JSON解析中间件
app.use(express.json());

// 2. 优先挂载API路由
app.use('/api', authRoutes);

// 3. 再配置Angular静态文件服务
app.use(express.static(browserDistFolder, {
  maxAge: '1y',
  index: 'index.html',
}));

// 4. 最后配置Angular SSR引擎路由
const commonEngine = new CommonEngine();

app.get('*', (req, res, next) => {
  const { protocol, originalUrl, baseUrl, headers } = req;

  commonEngine
    .render({
      bootstrap: () => import('./src/main.server'),
      documentFilePath: indexHtml,
      url: `${protocol}://${headers.host}${originalUrl}`,
      publicPath: browserDistFolder,
      providers: [{ provide: APP_BASE_HREF, useValue: baseUrl }],
    })
    .then((html) => res.send(html))
    .catch((err) => next(err));
});

const port = process.env['PORT'] || 4000;
app.listen(port, () => {
  console.log(`Node Express server listening on http://localhost:${port}`);
});

2. 配置Vite开发环境代理

在vite.config.ts中添加代理规则,将/api请求转发到Express服务器端口,避免Vite误判为前端资源:

import { defineConfig } from 'vite';
import angular from '@angular/vite-plugin-angular';

export default defineConfig({
  plugins: [angular()],
  server: {
    proxy: {
      '/api': {
        target: 'http://localhost:4000',
        changeOrigin: true,
      },
    },
  },
});

3. 验证前端请求写法

确保前端fetch请求路径正确,示例:

async login(username: string, password: string) {
  const response = await fetch('/api/login', {
    method: 'POST',
    headers: {
      'Content-Type': 'application/json',
    },
    body: JSON.stringify({ username, password }),
  });
  return response.json();
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.22 03:35:54