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

用户注册后个人资料更新失败问题求助:Postman可正常执行,前端疑似引发JSON解析错误

解决前端更新用户资料时的JSON解析错误与请求pending问题

首先咱们来定位问题根源:你的后端用了formidable来处理multipart/form-data格式的请求(因为要支持图片上传),但前端的请求配置和数据格式完全不匹配,导致了两个核心问题:

  • 直接传user对象时,请求头设了Content-Type: application/json,但实际发送的是FormData格式内容,后端的body-parser试图把它解析成JSON,自然抛出语法错误
  • 用JSON.stringify(user)时,因为user里包含File类型的图片数据,JSON无法序列化二进制内容,导致请求卡住pending

第一步:修正前端Action代码

更新你的update action,移除手动设置的Content-Type头(FormData会自动生成带边界标识的正确multipart/form-data请求头),直接传递FormData作为请求体:

export const update = (userId, token, userFormData) => {
  return fetch(`${API}/user/${userId}`, {
    method: "PUT",
    headers: {
      Accept: 'application/json',
      // 移除Content-Type,让浏览器自动处理
      Authorization: `Bearer ${token}`
    },
    body: userFormData // 直接传递FormData实例
  })
  .then(res => {
    return res.json();
  })
  .catch(err => {
    console.log(err);
  });
};

第二步:修正前端组件的表单数据处理逻辑

当前的handleChange每次修改字段都会新建FormData,导致之前的字段丢失,应该维护一个全局的FormData实例,每次修改时更新对应字段:

const UserProfileUpdate = ({match}) => {
  const [values, setValues] = useState({
    firstname: '',
    lastname: '',
    email: '',
    photo: '',
    about: '',
    error: false,
    success: false,
    userData: new FormData() // 初始化空的FormData实例
  });
  const {about,userData, photo, firstname, lastname, email, error, success} = values;
  const {user: { _id }} = isAuthenticated();
  const token = isAuthenticated().token;

  const init = userId => {
    read(userId, token).then(data => {
      if(data.error){
        setValues({...values, error: true})
      } else {
        // 用现有用户数据初始化FormData
        const initialFormData = new FormData();
        initialFormData.set('firstname', data.firstname);
        initialFormData.set('lastname', data.lastname);
        initialFormData.set('email', data.email);
        initialFormData.set('about', data.about);
        
        setValues({
          ...values,
          firstname: data.firstname,
          lastname: data.lastname,
          email: data.email,
          photo: data.photo,
          about: data.about,
          userData: initialFormData
        })
      }
    })
  };

  useEffect(() => {
    init(match.params.userId);
  }, []);

  const handleChange = name => e => {
    const value = name === 'photo' ? e.target.files[0] : e.target.value;
    // 基于现有FormData更新字段,避免丢失之前的内容
    const updatedFormData = new FormData(userData);
    updatedFormData.set(name, value);
    
    setValues({
      ...values,
      [name]: value,
      userData: updatedFormData,
      error: false,
      success: false
    });
  };

  // handleSubmit逻辑保持不变,直接传递维护好的userData即可
  const handleSubmit = e => {
    e.preventDefault();
    update(match.params.userId, token, userData).then(data => {
      if (data.error) {
        console.log(data.error);
      } else {
        updateUser(data, () => {
          setValues({
            ...values,
            firstname: data.firstname,
            lastname: data.lastname,
            email: data.email,
            about: data.about,
            success: true
          });
        });
      }
    });
  };

  const redirectUser = (success) => {
    if(success){
      return <Redirect to={`/dashboard/${_id}/`}/>
    }
  }

  // 组件其余渲染逻辑...
};

为什么这样能解决问题?

  1. 请求格式匹配:后端的formidable专门处理multipart/form-data请求,前端传递FormData时,浏览器会自动设置正确的请求头(包含boundary参数),后端能正确解析字段和文件
  2. 避免JSON序列化错误:FormData原生支持文件上传,不需要手动序列化,解决了JSON无法处理二进制数据的问题
  3. 完整的表单数据:每次修改时基于现有FormData更新字段,不会丢失之前填写的内容

这样修改后,前端的请求就能和Postman一样正常工作,后端也能正确解析并处理用户资料的更新了。

内容的提问来源于stack exchange,提问作者Emmanuel Oga

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.29 20:12:43