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

PUT请求出现Failed to fetch错误,MyBatis Mapper方法执行异常求助

问题描述

使用PUT请求更新用户资料时遇到Failed to fetch错误,对应的MyBatis Mapper方法也未正常执行。以下是问题详情及已尝试的排查步骤:

问题详情

尝试通过PUT请求更新用户资料时,服务器已接收请求,但请求一直处于pending状态。服务器日志显示请求处理方法已被调用,但MyBatis Mapper方法未按预期执行,数据库未更新且无错误日志输出。

代码片段

JavaScript代码

document.addEventListener('DOMContentLoaded', function () {
  const csrfToken = document.querySelector('meta[name="_csrf"]').getAttribute('content');
  const csrfHeader = 'X-CSRF-TOKEN';

  const pfpContainer = document.getElementsByClassName("pfp-container")[0];
  const soloProfilePicture = document.getElementById("solo-pfp");
  const pfpInput = document.getElementById("solo-pfp-file-input");
  const saveBtn = document.getElementById("save-profile-update-btn");

  pfpContainer.addEventListener("click", function () {
    pfpInput.click();
  });

  pfpInput.addEventListener("change", function (changeEvent) {
    const file = changeEvent.target.files[0];
    if (file) {
      const reader = new FileReader();
      reader.onload = function (loadEvent) {
        soloProfilePicture.src = loadEvent.target.result;
      };
      reader.readAsDataURL(file);
    }
  });

  saveBtn.onclick = function (event) {
    console.log("click");
    const data = {
      profileImageUrl: document.getElementById("solo-pfp").src,
      email: document.getElementById("email").innerText
    };

    fetch('/api/user/solo/update-profile', {
      method: 'PUT',
      headers: {
        [csrfHeader]: csrfToken,
        'Content-Type': 'application/json; charset=utf-8'
      },
      body: JSON.stringify(data)
    })
    .then(response => response.json())
    .then(resp => {
      alert("User Info Edit complete");
      window.location.href = "/";
    })
    .catch(error => {
      alert(JSON.stringify(error));
    });
  });
});

Spring Boot控制器代码

@PutMapping({"/solo/update-profile"})
public ResponseEntity<?> updateProfileProcess(@RequestBody UserResponseDTO user,
    HttpSession session) {
  log.info("UserResponseDTO 생성 성공");
  log.info("1. updateProfileProcess 호출됨");
  log.info("2. Received user data: {}", user);
  try {
    userService.updateProfileImageUrl(user);
    log.info("3. updateProfileImageUrl 호출됨");
  } catch (Exception e) {
    log.error("Error updating profile image URL: ", e);
    return ResponseEntity.badRequest().body("Error updating profile: " + e.getMessage());
  }

  Authentication auth = SecurityContextHolder.getContext().getAuthentication();
  log.info("4. Authentication 객체 생성됨");
  if (auth != null && auth.isAuthenticated()) {
    log.info("5. 세션이 NULL이 아니고 로그인이 되어있음");
    session.setAttribute("profileImageUrl", user.getProfileImageUrl());
    log.info("6. 세션에 정보 삽입함");
  }
  return ResponseEntity.ok()
      .body(Map.of("message", "Profile updated successfully", "redirectUrl", "/user/solo/"));
}

MyBatis Mapper XML代码

<mapper namespace="com.spring.moji.mapper.UserMapper">
  <resultMap id="userMap" type="com.spring.moji.entity.UserEntity">
    <id column="email" property="email"/>
    <result column="user_name" property="userName"/>
    <result column="birthday" property="birthday"/>
    <result column="gender" property="gender"/>
    <result column="password" property="password"/>
    <result column="created_at" property="createdAt"/>
    <result column="profile_image_url" property="profileImageUrl"/>
    <result column="couple_id" property="coupleId"/>
    <collection property="authList" resultMap="authMap"/>
  </resultMap>
  <resultMap id="authMap" type="com.spring.moji.entity.UserAuthEntity">
    <id column="auth_no" property="authNo"/>
    <result column="user_email" property="userEmail"/>
    <result column="auth" property="auth"/>
  </resultMap>

  <select id="login" resultMap="userMap">
    SELECT u.email, u.user_name, birthday, gender, password, profile_image_url, auth, couple_id
    FROM users u
    JOIN user_auth auth ON u.email = auth.user_email
    WHERE u.email = #{email}
  </select>

  <insert id="join">
    INSERT INTO users (email, user_name, birthday, gender, password, created_at)
    VALUES (#{email}, #{userName}, #{birthday}, #{gender}, #{password}, sysdate)
  </insert>

  <insert id="insertAuth">
    INSERT INTO user_auth (auth_no, user_email, auth)
    VALUES (user_auth_seq.nextval, #{userEmail}, #{auth})
  </insert>

  <update id="updateProfileImageUrl" parameterType="com.spring.moji.entity.UserEntity">
    UPDATE users
    SET profile_image_url = #{profileImageUrl}
    WHERE email = #{email}
  </update>
</mapper>

已尝试的排查步骤

  • 服务器日志:检查服务器日志,未发现请求处理相关的错误或警告。
  • JavaScript Fetch API:验证fetch请求已正确配置CSRF令牌和请求头。
  • 网络活动:监控网络请求,确认请求已发送但始终处于pending状态。
  • 数据库检查:确保数据库连接和updateProfileImageUrl查询配置正确。

疑问

  • PUT请求为何一直处于pending状态无法完成?
  • 什么原因导致MyBatis Mapper方法未执行或未更新数据库?
  • 提供的代码片段中是否存在常见问题或配置错误导致该问题?

恳请各位提供解决建议或指导,谢谢!


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.18 04:22:06