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

NextJS项目中如何在页面展示API返回的登录错误信息?

Next.js 登录表单错误提示实现方案

核心思路:静态内容保SEO,交互逻辑用CSR

登录页的静态结构(标题、表单框架、SEO元数据)可以通过Next.js的预渲染(SSG/SSR)保证搜索引擎抓取,而表单提交、错误提示这类用户触发的交互逻辑,直接在客户端处理即可,完全不需要额外新增SSR的LoginResult页面,和你之前Razor里的AJAX局部更新逻辑对齐。


具体实现步骤(以App Router为例)

  1. 页面基础结构(兼顾SEO)
    页面的静态元数据(标题、描述)通过Next.js的metadata配置预渲染,确保搜索引擎能抓取到核心信息;表单本身用客户端组件处理交互。

  2. 状态管理与表单提交
    用React的useState存储错误信息、用户名和密码,表单提交时阻止默认跳转,调用后端API后更新错误状态,在页面局部渲染提示。

// app/login/page.tsx
'use client';

import { useState } from 'react';

// SEO元数据,预渲染给搜索引擎
export const metadata = {
  title: '登录 - 我的网站',
  description: '请输入用户名和密码登录您的账户',
};

export default function LoginPage() {
  const [apiErrorMessage, setApiErrorMessage] = useState<string | null>(null);
  const [username, setUsername] = useState('');
  const [password, setPassword] = useState('');

  const handleSubmit = async (e: React.FormEvent<HTMLFormElement>) => {
    e.preventDefault();
    setApiErrorMessage(null); // 清空历史错误

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

      const data = await res.json();
      if (!res.ok) {
        // 渲染后端返回的错误信息
        setApiErrorMessage(data.apiErrorMessage || '登录失败,请重试');
        return;
      }

      // 登录成功逻辑:跳转首页、存储token等
      window.location.href = '/';
    } catch (err) {
      setApiErrorMessage('网络异常,请稍后再试');
    }
  };

  return (
    <div className="login-wrap">
      <h1>用户登录</h1>
      {/* 局部渲染错误提示 */}
      {apiErrorMessage && (
        <div className="error-box" style={{ color: 'red', marginBottom: '1rem' }}>
          {apiErrorMessage}
        </div>
      )}
      <form onSubmit={handleSubmit}>
        <div className="form-group">
          <label>用户名</label>
          <input
            type="text"
            value={username}
            onChange={(e) => setUsername(e.target.value)}
            required
          />
        </div>
        <div className="form-group">
          <label>密码</label>
          <input
            type="password"
            value={password}
            onChange={(e) => setPassword(e.target.value)}
            required
          />
        </div>
        <button type="submit" className="login-btn">登录</button>
      </form>
    </div>
  );
}
  1. 后端API转发(可选)
    可以在Next.js里创建API路由转发请求到你的后端,避免跨域问题:
// app/api/login/route.ts
import { NextResponse } from 'next/server';

export async function POST(request: Request) {
  const payload = await request.json();
  const res = await fetch(`${process.env.BACKEND_API_BASE}/login`, {
    method: 'POST',
    headers: { 'Content-Type': 'application/json' },
    body: JSON.stringify(payload),
  });

  const data = await res.json();
  return NextResponse.json(data, { status: res.status });
}

关于SSR/CSR/useEffect的纠结点解答

  • SSR:没必要用SSR处理错误提示,错误信息是用户提交后才产生的,预渲染时根本没有这些数据,强行用SSR只会增加服务器无意义的计算。
  • useEffect:不需要专门用useEffect监听状态触发请求,直接在表单提交事件里处理逻辑更直接,避免不必要的请求触发。
  • SEO:页面的静态内容已经通过metadata预渲染,搜索引擎能正常抓取,完全满足SEO需求。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.01 12:01:11