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

Next.js 13.4.4同时使用Server Action与Middleware时加载失败

问题:带Server Action的客户端表单在Middleware作用下渲染失败

当使用标记"use client"的表单搭配Server Action函数时,若Middleware作用于该表单所在路由,应用会渲染失败并报错:
错误截图

客户端表单代码(page.jsx)

"use client"

import {
  Container,
  Avatar,
  Button,
  CssBaseline,
  TextField,
  FormControlLabel,
  Checkbox,
  Link,
  Grid,
  Box,
  Typography,
} from 'components/mui';
import { peformSubmit } from './formSubmit';

export const SignInSide = () => {
  
  const action = async (e) => {
    await peformSubmit(e)
  }  

return (
  <Container component="main" maxWidth="xs">
    <CssBaseline />
    <Box
      sx={{
        marginTop: 8,
        display: 'flex',
        flexDirection: 'column',
        alignItems: 'center',
      }}
    >
      <Avatar sx={{ m: 1, bgcolor: 'secondary.main' }}>
        
      </Avatar>
      <Typography component="h1" variant="h5">
        Sign in
      </Typography>
      <Box component={"form"} action={action}  noValidate sx={{ mt: 1 }} method={"null"}>
        <TextField
          margin="normal"
          required
          fullWidth
          id="email"
          label="Email Address"
          name="email"
          autoComplete="email"
          autoFocus
        />
        <TextField
          margin="normal"
          required
          fullWidth
          name="password"
          label="Password"
          type="password"
          id="password"
          autoComplete="current-password"
        />
        <FormControlLabel
          control={<Checkbox value="remember" color="primary" />}
          label="Remember me"
        />
        <Button
          type="submit"
          fullWidth
          variant="contained"
          sx={{ mt: 3, mb: 2 }}
        >
          Sign In
        </Button>
        <Grid container>
          <Grid item xs>
            <Link href="#" variant="body2">
              Forgot password?
            </Link>
          </Grid>
          <Grid item>
            <Link href="#" variant="body2">
              {"Don't have an account? Sign Up"}
            </Link>
          </Grid>
        </Grid>
      </Box>
    </Box>
  </Container>
  );
};

SignInSide.needAuth = false;

export default SignInSide;

Server Action代码(peformSubmit.js)

'use server';

export async function peformSubmit (formData){
    console.log({
      email: formData.get('email'),
      password: formData.get('password'),
    });
};

Middleware代码(middleware.js)

import { NextResponse } from "next/server";
import { needAuth as _needAuth } from "./lib/needAuth";
import { AUTH } from 'routes';

export const config = { matcher: ["/auth"] }

export async function middleware(request) {
  const needAuth = await _needAuth(request)
  console.log(request.url)

  if(needAuth){
    return NextResponse.redirect(new URL('/auth', request.url))
  }

  return NextResponse.next()
}

MUI组件导出代码(components/mui/index.js)

"use client";
export * from "@mui/material";

测试情况

  • 移除表单的action属性后,应用可正常运行;
  • 移除Middleware(或在匹配规则中排除该页面)后,应用可正常运行;
  • 即使Middleware仅保留console.log并返回NextResponse.next(),仍会出现相同错误。

期望目标

实现表单结合Server Action正常工作,同时使用Middleware保护路由访问。示例中的匹配规则使用"/auth"仅为测试,实际需求是让其他表单也能在Middleware保护下正常工作。

package.json内容

{
  "name": "authTest",
  "version": "0.1.0",
  "private": true,
  "scripts": {
    "dev": "next dev",
    "build": "next build",
    "start": "next start",
    "lint": "next lint"
  },
  "dependencies": {
    "@emotion/react": "^11.11.0",
    "@emotion/styled": "^11.11.0",
    "@mswjs/data": "^0.13.0",
    "@mui/icons-material": "^5.11.16",
    "@mui/material": "^5.13.4",
    "bcrypt": "^5.1.0",
    "eslint": "8.42.0",
    "eslint-config-next": "13.4.4",
    "mongoose": "^7.2.1",
    "next": "13.4.4",
    "react": "^18.2.0",
    "react-dom": "^18.2.0"
  },
  "devDependencies": {
    "@types/bcryptjs": "^2.4.2"
  }
}

内容的提问来源于stack exchange,提问作者Facundo E. Villagra

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.19 11:04:58