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

Next.js API路由本地正常但生产环境提交评论报错求助

生产环境提交评论失败问题排查与修复

API路由代码问题与修复

原API路由存在以下几个核心问题,直接导致生产环境报错:

  1. 未捕获异步操作异常:Sanity的create操作失败时会抛出错误,未处理的异常会让API返回500错误
  2. 未正确完成响应:仅设置status(200)但未发送响应体,会导致请求挂起超时
  3. 未限制请求方法:未校验请求是否为POST,其他请求方法会引发错误
  4. Client初始化逻辑冗余:每次请求都重新配置client,应该在路由外初始化复用

修复后的API路由代码:

import client from '@sanity/client'

// 全局初始化Sanity客户端,避免重复配置
const sanityClient = client({
  projectId: process.env.SANITY_PROJECT_ID,
  dataset: process.env.SANITY_DATASET,
  apiVersion: '2023-05-03',
  useCdn: false // 写入操作禁用CDN
})

export default async function CreateComment(req, res) {
  // 仅处理POST请求
  if (req.method !== 'POST') {
    return res.status(405).json({ message: '仅支持POST请求' })
  }

  try {
    const { name, comment, _id } = JSON.parse(req.body)
    
    await sanityClient.config({
      token: process.env.SANITY_AUTH_TOKEN
    }).create({
      _type: "comment",
      name,
      comment,
      blog:{
        _type: "reference",
        _ref: _id
      },
    })

    return res.status(200).json({ success: true, message: '评论提交成功' })
  } catch (error) {
    console.error('创建评论失败:', error)
    return res.status(500).json({ success: false, message: '评论提交失败', error: error.message })
  }
}

表单组件代码问题与修复

原表单组件的问题会导致生产环境下请求未完成就刷新,或无法感知请求失败:

  1. fetch未使用await且未处理错误:无法确认请求是否成功完成
  2. 按钮onClick提前触发刷新:网络延迟时,评论还没提交完成就刷新页面
  3. 未设置请求头:部分生产环境服务器需要明确指定Content-Type
  4. 错误提示不明确:用户无法知晓具体的验证失败原因

修复后的表单组件代码:

import { useForm } from "react-hook-form";

function Form({ _id }) {
  const {
    register,
    handleSubmit,
    formState: { errors },
    reset,
  } = useForm();

  const onSubmit = async (data) => {
    try {
      const response = await fetch('/api/CreateComment', {
        method: "POST",
        headers: {
          'Content-Type': 'application/json',
        },
        body: JSON.stringify({ ...data, _id })
      })

      const result = await response.json()
      if (result.success) {
        reset() // 提交成功后清空表单
        setTimeout(() => {
          window.location.reload()
        }, 3000);
      } else {
        alert(result.message)
      }
    } catch (error) {
      console.error('提交评论失败:', error)
      alert('评论提交失败,请稍后重试')
    }
  }

  return (
    <form id='my-form' onSubmit={handleSubmit(onSubmit)}>
      <div>
        <label htmlFor="name">你的名字</label>
        <input 
          {...register('name', { 
            required: "请填写名字", 
            minLength: { value: 3, message: "名字至少3个字符" } 
          })} 
          type="text" 
          id="name" 
        />
        {errors.name && <span style={{color: 'red'}}>{errors.name.message}</span>}
        
        <div>
          <label htmlFor="comment">你的评论</label>
          <textarea 
            {...register('comment', { 
              required: "请填写评论", 
              minLength: { value: 5, message: "评论至少5个字符" } 
            })} 
            id="comment" 
            rows="4" 
          ></textarea>
          {errors.comment && <span style={{color: 'red'}}>{errors.comment.message}</span>}
        </div>
        
        <div>
          <button type="submit">
            发布评论
          </button>
        </div>
      </div>
    </form>
  );
}

export default Form;

额外排查点

  1. 生产环境环境变量:确认SANITY_AUTH_TOKEN、SANITY_PROJECT_ID等变量已在部署平台(如Vercel、Netlify)正确配置
  2. Sanity权限:检查SANITY_AUTH_TOKEN是否拥有创建comment文档的权限
  3. CORS设置:如果Sanity与网站域名不同,需在Sanity控制台配置正确的CORS origins

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.22 22:06:25