TypeScript封装Fetch发POST请求时Express后端req.body为空的问题
问题根源
你封装的post方法参数传递逻辑和调用逻辑不匹配,同时缺失默认的JSON请求头配置,两个问题共同导致后端无法解析请求体:
- 参数位置传错:你定义的
post函数第二个入参是请求体本身,第三个才是请求配置项。但你调用时把包含请求体、请求头的对象全部传给了第二个参数,导致:- 实际序列化的请求体是
{body: inputData, headers: {...}},而非你预期的inputData - 你设置的
Content-Type请求头没有被传入配置项,根本不会生效
- 实际序列化的请求体是
- 请求头缺失:Fetch发送JSON格式的POST请求时,默认
Content-Type为text/plain,而Express的express.json()中间件只会解析Content-Type为application/json的请求,请求头不匹配时自然不会解析请求体,req.body就为空对象。
修复方案
第一步:修正请求调用代码
把请求体和配置项分开放到对应参数位置:
const res = await fetch.post(`${url}/login`, inputData, { headers: { 'Content-Type': 'application/json' }, });
第二步(推荐):优化post封装逻辑,默认添加JSON请求头
避免每次调用都手动传请求头,同时合并用户自定义配置的优先级:
export async function post<T, U>( path: string, body: T, config?: RequestInit ): Promise<U> { // 合并默认请求头和用户自定义请求头,用户配置优先级更高 const mergedHeaders = { 'Content-Type': 'application/json', ...config?.headers } const init = { method: 'post', body: JSON.stringify(body), ...config, headers: mergedHeaders }; return await fetchWrapper<U>(path, init); }
优化后调用代码可以简化为:
const res = await fetch.post(`${url}/login`, inputData);
内容的提问来源于stack exchange,提问作者Shakhzod Yokubov
相关产品推荐
相关产品推荐

