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

Next.js应用部署到Vercel后登录注册功能失效 报404及JSON解析错误

问题描述

我开发完成了一个Next.js应用,在本地测试构建版本时运行完全正常,但部署到Vercel后尝试登录或注册时功能无法生效,收到SyntaxError: Unexpected end of JSON input错误,同时API路由返回404错误。我已经反复核对过环境变量配置,以下是上下文的API请求代码:

// AuthContext.js
// Register user
const register = async (user) => {
  const res = await fetch(`${NEXT_URL}/api/register`, {
    method: "POST",
    headers: {
      "Content-Type": "application/json",
    },
    body: JSON.stringify(user),
  });

  const data = await res.json();

  if (res.ok) {
    setUser(data.user);
    router.push("/account/dashboard");
  } else {
    setError(data.message);
    setError(null);
  }
};

// Login user
const login = async ({ email: identifier, password }) => {
  const res = await fetch(`${NEXT_URL}/api/login`, {
    method: "POST",
    headers: {
      "Content-Type": "application/json",
    },
    body: JSON.stringify({
      identifier,
      password,
    }),
  });

  const data = await res.json();

  if (res.ok) {
    setUser(data.user);
    router.push("/account/dashboard");
  } else {
    setError(data.message);
    setError(null);
  }
};

// Logout user
const logout = async () => {
  const res = await fetch(`${NEXT_URL}/api/logout`, {
    method: "POST",
  });

  if (res.ok) {
    setUser(null);
    router.push("/");
  }
};

// Check if user is logged in
const checkUserLoggedIn = async (user) => {
  const res = await fetch(`${NEXT_URL}/api/user`);
  const data = await res.json();

  if (res.ok) {
    setUser(data.user);
  } else {
    setUser(null);
  }
}; 

API路由代码:

// api/login.js
import cookie from 'cookie'
import { API_URL } from '@/config/index'

export default async (req, res) => {
  if (req.method === 'POST') {
    const { identifier, password } = req.body

    const strapiRes = await fetch(`${API_URL}/auth/local`, {
      method: 'POST',
      headers: {
        'Content-Type': 'application/json',
      },
      body: JSON.stringify({
        identifier,
        password,
      }),
    })

    const data = await strapiRes.json()

    if (strapiRes.ok) {
      // Set Cookie
      res.setHeader(
        'Set-Cookie',
        cookie.serialize('token', data.jwt, {
          httpOnly: true,
          secure: process.env.NODE_ENV !== 'development',
          maxAge: 60 * 60 * 24 * 7, // 1 week
          sameSite: 'strict',
          path: '/',
        })
      )

      res.status(200).json({ user: data.user })
    } else {
      res
        .status(data.statusCode)
        .json({ message: data.message[0].messages[0].message })
    }
  } else {
    res.setHeader('Allow', ['POST'])
    res.status(405).json({ message: `Method ${req.method} not allowed` })
  }
}
解决方案

按以下优先级排查修复即可:

  • 移除请求前缀的NEXT_URL:同站API请求不需要拼接域名,直接写/api/xxx即可,fetch会自动补全当前站点域名,完全避免NEXT_URL配置错误导致的404问题。如果一定要保留NEXT_URL,确保Vercel环境变量中配置的NEXT_URL是你站点的完整公网域名,不要带末尾斜杠,也不要填写本地localhost地址。
  • 添加响应解析兜底逻辑:直接对非200响应调用res.json()会因为空响应体抛出JSON解析错误,你需要用try catch包裹解析逻辑,或者先判断响应状态再处理:
const res = await fetch('/api/login', {/* 请求配置 */})
let data = {}
try {
  data = await res.json()
} catch (e) {
  data = { message: '请求异常,请稍后重试' }
}
// 后续业务逻辑
  • 检查API路由文件路径与大小写:Vercel部署环境对文件路径大小写敏感,确保pages/api目录下的文件名称、层级和代码中调用的路径完全一致,不存在大小写拼写差异。
  • 确认后端服务连通性:检查Vercel环境变量中配置的API_URL是公网可访问的Strapi服务地址,没有填写本地内网地址,确保Vercel服务器可以正常访问到你的后端服务。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.06 15:39:05