使用表单数据编辑照片和文本数据时发生服务器错误 500

Server error 500 occurred when editing photo and text data using form data

提问人:hee kim 提问时间:9/9/2023 更新时间:9/9/2023 访问量:18

问:

当向服务器发送请求以使用照片和文本数据修补表单数据以修改用户信息时,服务器会发送 500 错误。 这是我的代码:客户端编写的代码有问题吗?

UploadProfileImg 文件:这是我的文件。它显示用户先前选择的图像,当用户编辑图像时,它会在圆形空间中显示新选择文件的预览。UploadProfileImg

import React, { useState, useEffect } from 'react';

const UploadProfileImg = ({ setImageFile, currentImageUrl }: any) => {
  const [previewImage, setPreviewImage] = useState<string | null>(currentImageUrl);
  const fileInputRef = React.createRef<HTMLInputElement>();

  useEffect(() => {
    setPreviewImage(currentImageUrl);
  }, [currentImageUrl]);

  const handleImageChange = (event: React.ChangeEvent<HTMLInputElement>) => {
    const file = event.target.files?.[0];
    if (file) {
      setPreviewImage(URL.createObjectURL(file));
      setImageFile(file);
    }
  };

  const handleClickUploadArea = () => {
    if (fileInputRef.current) {
      fileInputRef.current.click();
    }
  };

  const handleKeyPress = (event: React.KeyboardEvent<HTMLDivElement>) => {
    if (event.key === 'Enter') {
      handleClickUploadArea();
    }
  };

  return (
    <div
      role="button"
      tabIndex={0}
      onClick={handleClickUploadArea}
      onKeyPress={handleKeyPress}
      style={{
        width: '60px',
        height: '60px',
        borderRadius: '50%',
        cursor: 'pointer',
        backgroundColor: 'lightgray',
      }}
    >
      {previewImage && (
        <img src={previewImage} alt="Preview" style={{ width: '60px', height: '60px', borderRadius: '50%' }} />
      )}
      <input
        type="file"
        accept="image/jpeg"
        onChange={handleImageChange}
        style={{ display: 'none' }}
        ref={fileInputRef}
      />
    </div>
  );
};

export default UploadProfileImg;

EditUserProfile 文件:这是我的文件。在这里,用户可以编辑他们的昵称、电话号码和地址。用户完成修改后,代码将用户的输入和个人资料图像作为 FormData 发送到服务器。EditUserProfile

import styled from 'styled-components';
import {
  MainContainer,
  PageTitle,
  RegisterInputWrapper,
  InputContainer,
  InputLabelStyle,
  InputStyle,
} from './RegisterPet';
import { Link } from 'react-router-dom';
import Button from '@mui/material/Button';
import Textarea from '@mui/joy/Textarea';
import { useSelector } from 'react-redux';
import { IUser } from '../modules/userSlice';
import { getCookieValue } from 'hooks/getCookie';
import { useForm } from 'react-hook-form';
import axios, { AxiosError } from 'axios';
import UploadProfileImg from '../components/UploadProfileImg';
import { useState } from 'react';

interface FormData {
  nickName: string;
  phone: string;
  address: string;
  body: string;
}

const apiUrl = process.env.REACT_APP_API_URL;

const EditUserProfile = () => {
  const { name, memberId, phone, address, email, nickName, body, petsitterBoolean, photo } = useSelector(
    (state: IUser) => state.login,
  );

  const [imageFile, setImageFile] = useState<File | null>(null);

  const handleImageFileChange = (file: File) => {
    setImageFile(file);
  };

  const { register, handleSubmit } = useForm<FormData>();

  const onSubmit = async (requestbody: FormData) => {
    const token = getCookieValue('access_token');

    const formData = new FormData();
    if (imageFile) {
      formData.append('file', imageFile);
    }
    formData.append('requestBody', JSON.stringify(requestbody));
    console.log(requestbody);

    try {
      console.log(token);
      const response = await axios.patch(`${apiUrl}/members/${memberId}`, formData, {
        headers: {
          Authorization: `Bearer ${token}`,
          'Content-Type': 'multipart/form-data',
        },
      });
      console.log(response.data);
    } catch (error) {
      if (error instanceof AxiosError) {
        if (error.response) {
          console.error(error.response.data);
        } else {
          console.error('AxiosError caught (no response):', error.message);
        }
      } else {
        console.error('Non-Axios error caught:', error);
      }
    }
  };

  return (
    <>
      <PageTitle>Edit Users</PageTitle>
      <UploadProfileImg setImageFile={handleImageFileChange} />
      <MainContainer>
        <InputContainer onSubmit={handleSubmit(onSubmit)}>
          <RegisterInputWrapper>
            <InputLabelStyle htmlFor="username">Name</InputLabelStyle>
            <Info>{name}</Info>
          </RegisterInputWrapper>
          <RegisterInputWrapper>
            <InputLabelStyle htmlFor="email">Email</InputLabelStyle>
            <Info>{email}</Info>
          </RegisterInputWrapper>
          <RegisterInputWrapper>
            <InputLabelStyle htmlFor="nickName">Nickname</InputLabelStyle>
            <InputStyle type="text" defaultValue={nickName} {...register('nickName')} />
          </RegisterInputWrapper>
          <RegisterInputWrapper>
            <InputLabelStyle htmlFor="phone">Phone</InputLabelStyle>
            <InputStyle type="text" defaultValue={phone} {...register('phone')} />
          </RegisterInputWrapper>
          <RegisterInputWrapper>
            <InputLabelStyle htmlFor="address">Address</InputLabelStyle>
            <InputStyle type="text" defaultValue={address} {...register('address')} />
          </RegisterInputWrapper>
          <RegisterInputWrapper>
            <InputLabelStyle htmlFor="body">About me</InputLabelStyle>
            <Textarea
              minRows={3}
              sx={{
                width: '60%',
                borderColor: '#A6A6A6',
                borderRadius: '8px',
                fontSize: 14,
              }}
              defaultValue={body}
              {...register('body')}
            />
          </RegisterInputWrapper>
          <Button type="submit" variant="contained" sx={{ backgroundColor: '#279eff', mt: 5 }}>
            edit
          </Button>
        </InputContainer>
      </MainContainer>
    </>
  );
};

const Info = styled.div`
  ${(props) => props.theme.fontSize.s14h21};
  width: 60%;
`;

const LinkContainer = styled.div`
  display: flex;
  justify-content: space-between;
  width: 100%;
`;

export default EditUserProfile;

用于更新用户信息的服务器 API:服务器 API 用于在更新用户信息时发送 PATCH 请求。下面是用于更新用户信息的 CURL 请求示例:

curl --location --request PATCH 'http://localhost:8080/members/1' \
--form 'requestBody="{
    \"nickName\": \"kimcoding\",
    \"phone\": \"01011111111\",
    \"address\": \"06160 Seoul 415 1\",
    \"body\" : \"Hello, I'm coding Kim.\"
}";type=application/json' \
--form 'file=@"/D:/KITAE/Downloads/cat002.jpeg"'

服务器需要 FormData 格式的数据。这些更改应在“requestBody”键下进行,其值类似于 。如果文件有更改,可以使用附加 JPEG 文件的“file”键发送。{ "nickName": "kingcoding", "phone": "01011111111", "address": "06160 Seoul ]415 1st floor", "body" : "Hello, world!"

即使我发送了一个补丁请求,删除了对图像文件的修改,并首先只修改了文本,服务器 500 错误仍然发生。我想知道这是否是因为 requestBody 中也有键和值属性,或者当从服务器接收数据时,是否会通过接收每个项目、昵称、电话和地址的键值而不是 requestBody 来解析它 { “昵称”: “member1”, “phone”: “01011111111”, “address”: “06160 首尔 415”, }

reactjs typescript 错误处理 axios react-hook-form

评论


答: 暂无答案