使用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,避免跨域。
- 让后端团队在API服务器配置CORS,允许你的前端域名(比如
代理接口示例(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 葛城
相关产品推荐
相关产品推荐

