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

使用LocalStorage中的Token发送POST请求时遭遇JSON构造无效错误的排查求助

排查LocalStorage获取Token发送POST请求返回「invalid json construct」的问题

问题描述

我在使用以下代码通过LocalStorage获取Token发送POST请求创建管理员时遇到异常:该请求在Postman和Hoppscotch中可正常执行,但代码运行时持续返回invalid json construct错误,响应内容为:{data: null, error: "invalid json construct", message: "", statuscode: 422}。

相关代码如下:

export const addAdmin = (values) => async (dispatch) => {
  var add = localStorage.getItem('user');
  const res = await fetch('https://capitalluxurydev.xyz/v1/admin/createadmin', {
    method: 'POST',
    body: JSON.stringify(values),
    headers: {
      Authorization: add,
      'Content-Type': 'application/json; charset=utf-8',
    },
    credentials: 'same-origin',
  });
  try {
    const data = await res.json();
    console.log(data);
    return;
  } catch (error) {
    console.log(error);
    return;
  }
};

可能的原因分析

  • Authorization头格式错误:你直接把localStorage.getItem('user')的结果放到Authorization头里,但user很可能是一个包含Token的完整用户对象JSON字符串,而非纯Token值。这种情况下,请求头的格式不符合后端预期,会干扰整个请求的解析流程,导致后端无法正确处理JSON请求体。
  • 请求体JSON无效:如果values对象中包含JSON.stringify无法序列化的内容(比如函数、Symbol类型、循环引用),生成的JSON字符串会损坏,后端解析时就会抛出「invalid json construct」错误。
  • 跨域凭证配置不匹配:credentials: 'same-origin'在跨域场景下会阻止凭证(比如Cookie)的传递,如果后端需要凭证才能正常解析请求,或者CORS配置不匹配,也可能间接引发这个问题。

解决方案

1. 修复Authorization头的Token格式

首先检查LocalStorage中user的实际内容:

console.log(localStorage.getItem('user'));

如果输出是类似{"token":"your-token-here", "username":"admin"}的JSON对象,需要先解析对象提取Token,并且注意很多后端要求Token前加上Bearer前缀:

// 修改获取Token的逻辑
const userStr = localStorage.getItem('user');
let token = '';
if (userStr) {
  try {
    const userObj = JSON.parse(userStr);
    token = userObj.token; // 根据实际字段名调整
  } catch (parseErr) {
    console.error('解析LocalStorage用户数据失败:', parseErr);
  }
}

// 更新请求头
headers: {
  Authorization: token ? `Bearer ${token}` : '', // 没有Token时可以处理为空或抛出错误
  'Content-Type': 'application/json; charset=utf-8',
},

如果后端不需要Bearer前缀,直接传递token即可。

2. 确保请求体可正常序列化

在调用JSON.stringify(values)前先测试序列化是否正常,提前发现问题:

try {
  const testJson = JSON.stringify(values);
  console.log('序列化后的请求体:', testJson);
} catch (serialErr) {
  console.error('请求体序列化失败:', serialErr);
  // 这里可以处理错误,比如过滤掉非可序列化的字段
}

如果发现序列化失败,需要清理values中的异常内容:

  • 移除函数、Symbol类型的字段;
  • 处理循环引用(可以使用第三方库如flatted来序列化循环引用对象);
  • 如果values包含文件,不能用JSON,需要改用FormData传递(同时后端要支持表单数据解析)。

3. 调整跨域凭证配置(跨域场景)

如果你的前端和后端部署在不同域名下,把credentials改为include:

credentials: 'include',

同时确保后端的CORS配置满足:

  • 设置Access-Control-Allow-Credentials: true;
  • Access-Control-Allow-Origin指定为你的前端域名(不能是*)。

4. 优化错误捕获逻辑

把整个请求流程包裹在try/catch中,提前捕获解析Token、序列化请求体时的错误,方便排查:

export const addAdmin = (values) => async (dispatch) => {
  try {
    // 1. 处理Token
    const userStr = localStorage.getItem('user');
    if (!userStr) {
      console.error('LocalStorage中无用户数据');
      return;
    }
    const userObj = JSON.parse(userStr);
    const token = userObj.token;

    // 2. 序列化请求体
    const serializedBody = JSON.stringify(values);

    // 3. 发送请求
    const res = await fetch('https://capitalluxurydev.xyz/v1/admin/createadmin', {
      method: 'POST',
      body: serializedBody,
      headers: {
        Authorization: `Bearer ${token}`,
        'Content-Type': 'application/json; charset=utf-8',
      },
      credentials: 'include',
    });

    // 4. 处理响应
    const data = await res.json();
    console.log(data);
    // 这里添加dispatch的业务逻辑,比如dispatch(addAdminSuccess(data))
  } catch (error) {
    console.error('请求处理出错:', error);
    // 处理错误,比如dispatch(addAdminFailure(error))
  }
};

内容的提问来源于stack exchange,提问作者Taiwo Sulaimon

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.29 08:07:29