Next.js中如何给GET请求添加Body调用指定API接口
问题
我需要通过GET请求调用接口http://localhost:8000/student/material获取课程资料,该接口必须携带Body{ "batch":"DRB2401" }才能正常工作(在Postman中可运行),但GET请求通常不支持Body,且后端未配置支持URL参数。我尝试了以下Next.js代码但无法正常请求,请问该如何解决?
import React, { useState, useEffect } from 'react'; import { Card, CardContent, Typography, Grid, ThemeProvider, createTheme } from '@mui/material'; import RootLayout from '@/layouts/RootLayout'; const MaterialPage = () => { const [materials, setMaterials] = useState([]); useEffect(() => { fetchMaterials(); }, []); const fetchMaterials = async () => { try { const response = await fetch('http://localhost:8000/student/material', { method: 'GET', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ batch: 'DRB2401' }) // Body needed for the endpoint }); if (response.ok) { const data = await response.json(); setMaterials(data); } else { throw new Error('Failed to fetch materials'); } } catch (error) { console.error('Error fetching materials:', error); } }; // Create a custom theme with the desired typography const theme = createTheme({ typography: { fontFamily: 'Arial, sans-serif' } }); return ( <ThemeProvider theme={theme}> <RootLayout> <Grid container spacing={2}> {materials.map(material => ( <Grid item xs={12} key={material._id}> <Card sx={{ backgroundColor: '#f0f0f0', padding: 2 }}> <CardContent> <Typography variant="h6" gutterBottom> {material.message} </Typography> <Typography variant="body1"> Sender: {material.sender} </Typography> {material.file && ( <Typography variant="body1"> File: {material.file} </Typography> )} </CardContent> </Card> </Grid> ))} </Grid> </RootLayout> </ThemeProvider> ); }; export default MaterialPage;
注:使用URL参数的方式不可行,因为后端未配置支持。
解决方案
方法1:改用POST请求(优先尝试)
虽然接口标注为GET,但它需要传递Body的特性更符合POST的语义。直接修改请求方法为POST,多数情况下后端只要能解析Body就会正常响应:
const fetchMaterials = async () => { try { const response = await fetch('http://localhost:8000/student/material', { method: 'POST', // 替换为POST方法 headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ batch: 'DRB2401' }) }); if (response.ok) { const data = await response.json(); setMaterials(data); } else { throw new Error('Failed to fetch materials'); } } catch (error) { console.error('Error fetching materials:', error); } };
方法2:通过Next.js API路由中转
如果后端强制要求GET方法,可以在Next.js里创建一个本地API路由作为中间层,由这个路由去发送带Body的GET请求,前端再调用本地接口:
- 创建中转路由(Pages Router为例,路径
pages/api/materials.js):
export default async function handler(req, res) { try { const response = await fetch('http://localhost:8000/student/material', { method: 'GET', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ batch: 'DRB2401' }) }); const data = await response.json(); res.status(response.status).json(data); } catch (error) { res.status(500).json({ error: 'Failed to fetch materials' }); } }
- 前端修改请求地址为本地API:
const response = await fetch('/api/materials', { method: 'GET' });
方法3:推动后端规范接口
GET请求带Body不符合HTTP标准,虽然Postman等工具支持,但浏览器的fetch以及多数HTTP客户端会忽略GET请求的Body。从长远维护角度,建议让后端做以下调整:
- 支持通过URL参数传递
batch(比如/student/material?batch=DRB2401) - 或者将接口改为POST方法,用Body传递参数
内容的提问来源于stack exchange,提问作者Mame
相关产品推荐
相关产品推荐

