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

使用NextJS与Fetch发送请求时遇Failed to fetch错误求助

解决NextJS中Fetch提交数据返回"Failed to fetch"的问题

以下是针对你遇到的问题的排查方向和解决方案:

1. 优先排查跨域(CORS)问题

"Failed to fetch"最常见的原因是浏览器跨域限制。如果你的前端域名和公司API域名不一致,浏览器会拦截请求。

  • 解决方案:
    • 让后端团队在API服务器配置CORS,允许你的前端域名(比如https://your-nextjs-app.com)的跨域请求;
    • 或者在NextJS中创建API路由代理:在pages/api/contact.js(App Router的话是app/api/contact/route.js)写一个代理接口,前端请求这个本地接口,再由它转发到公司API,避免跨域。

代理接口示例(Pages Router):

// pages/api/contact.js
export default async function handler(req, res) {
  if (req.method === 'POST') {
    try {
      const response = await fetch('公司API的真实URL', {
        method: 'POST',
        headers: {
          'Content-Type': 'application/json',
        },
        body: JSON.stringify(req.body),
      });
      const data = await response.json();
      res.status(response.status).json(data);
    } catch (error) {
      res.status(500).json({ error: '转发请求失败' });
    }
  } else {
    res.setHeader('Allow', ['POST']);
    res.status(405).end(`Method ${req.method} Not Allowed`);
  }
}

前端修改为请求本地代理:

fetch('/api/contact', { /* 其他参数不变 */ })

2. 完善Fetch的错误处理逻辑

原生Fetch只有网络请求完全失败时才会进入catch,如果API返回400、500这类HTTP错误状态码,它仍会进入then流程,此时调用response.json()可能会抛出错误,最终也会触发catch但信息模糊。

修改代码,先判断响应状态:

fetch('API_URL', {
  method: 'POST',
  headers: {
    'Content-Type': 'application/json'
  },
  body: JSON.stringify(submit)
})
.then(response => {
  if (!response.ok) {
    // 抛出HTTP错误信息,比如400、500
    throw new Error(`HTTP错误:${response.status} ${response.statusText}`);
  }
  return response.json();
})
.then(data => {
  console.log(data)
  alert('Mensagem enviada com sucesso!')
})
.catch(error => {
  console.error('请求详情错误:', error)
  alert('Erro ao enviar mensagem: ' + error.message)
})

3. 替换DOM取值方式(NextJS推荐写法)

在NextJS/React中,尽量避免直接用document.getElementById操作DOM,推荐用useState绑定表单值,更符合React的状态管理逻辑:

import { useState } from 'react';

function ContactForm() {
  const [formData, setFormData] = useState({
    nome: '',
    email: '',
    telefone: '',
    nome_empresa: '',
    mensagem: ''
  });

  const handleChange = (e) => {
    setFormData({
      ...formData,
      [e.target.id]: e.target.value
    });
  };

  const submitContact = async (e) => {
    e.preventDefault(); // 阻止表单默认提交行为
    try {
      const response = await fetch('API_URL', {
        method: 'POST',
        headers: {
          'Content-Type': 'application/json'
        },
        body: JSON.stringify(formData)
      });
      if (!response.ok) {
        throw new Error(`HTTP错误:${response.status}`);
      }
      const data = await response.json();
      console.log(data);
      alert('Mensagem enviada com sucesso!');
      // 重置表单
      setFormData({
        nome: '',
        email: '',
        telefone: '',
        nome_empresa: '',
        mensagem: ''
      });
    } catch (error) {
      console.error('提交失败:', error);
      alert('Erro ao enviar mensagem: ' + error.message);
    }
  };

  return (
    <form onSubmit={submitContact}>
      <input id="nome" value={formData.nome} onChange={handleChange} />
      <input id="email" value={formData.email} onChange={handleChange} />
      <input id="telefone" value={formData.telefone} onChange={handleChange} />
      <input id="empresa" value={formData.nome_empresa} onChange={handleChange} />
      <textarea id="mensagem" value={formData.mensagem} onChange={handleChange} />
      <button type="submit">提交</button>
    </form>
  );
}

export default ContactForm;

4. 基础检查项

  • 确认API_URL是正确的,没有拼写错误,且协议(HTTP/HTTPS)和前端一致(前端用HTTPS的话,API不能用HTTP,否则浏览器会阻止混合内容);
  • 打开浏览器开发者工具的Network面板,查看请求的详细状态:是否发送成功、响应头是什么、有没有返回具体错误信息;
  • 检查表单字段名是否和API要求的完全一致(比如nome_empresa是否是API期望的参数名)。

内容的提问来源于stack exchange,提问作者Katsuragi 葛城

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.17 17:31:02