【问题标题】:Error in PUT API request in reactJS fetch from frontend从前端获取 reactJS 中的 PUT API 请求错误
【发布时间】:2022-01-27 01:25:11
【问题描述】:

我正在发出PUT 请求更改user 的密码,这里我在前端使用reactJS,在后端使用express+mongoDB (MERN)。 API 在后端运行良好。

我的 API 正文 + 成功响应(仅使用后端)

但是当我创建前端页面并发出fetch 请求时,我在后端终端中收到此错误。

Illegal arguments: undefined, string

前端代码

import React, {useState} from "react";
import { useNavigate } from "react-router-dom";

const ChangePasswordPage = (props) => {
  let navigate = useNavigate();

  const [showPassword, setShowPassword] = useState(false);
  const [showConfmPassword, setShowConfmPassword] = useState(false);

  const [newCredentials, setNewCredentials] = useState({
    email: "",
    newPassword: "",
    confmNewPassword: "",
  });

  const onChange = (e) => {
    setNewCredentials({
      ...newCredentials,
      [e.target.name]:e.target.value,
    });
  };

  console.log(newCredentials);

  const handleSubmit = async (e) => {
    e.preventDefault();
    const response = await fetch("http://localhost:5000/api/changePassword",{
      method:"PUT",
      body: JSON.stringify({
        email: newCredentials.email,
        newPassword: newCredentials.newPassword,
        confmNewPassword: newCredentials.confmNewPassword,
      }),
    });

    const json = await response.json();
    console.log(json)

    if(json.success === true) {
      localStorage.setItem("token", json.authToken);
      props.showAlert("Password Changed Successfully !", "info");
      navigate("/login");
    } 
    else {
      props.showAlert("Password Did Not Changed", "danger")
    }
  }

  const backToForgot = () => {
    navigate("/forgotPassword");
  }

  function togglePasswordVisibilty() {
    setShowPassword(!showPassword ? true : false);
  }

  function toggleConfmPasswordVisibilty() {
    setShowConfmPassword(!showConfmPassword ? true : false);
  }


  return (
<>
      <div className="container my-3">
        <div
          id="loginbody"
          style={{ backgroundColor: "gainsboro", padding: "5%" }}
        >
          <div className="mt-3">
            <h2 className="my-3 display-3">Change Password</h2>
            <form className="login-form p-5" onSubmit={handleSubmit}>
              <div className="mb-3">
                <label htmlFor="exampleInputEmail1" className="form-label">
                  Email address
                </label>
                <input
                  type="email"
                  className="form-control"
                  id="email"
                  name="email"
                  value={newCredentials.email}
                  aria-describedby="emailHelp"
                  onChange={onChange}
                />
                <div id="emailHelp" className="form-text">
                  Type email again to ensure your identity.
                </div>
              </div>

              <div className="mb-3">
                <div
                  className="pass-wrapper"
                  style={{ display: "flex", alignItems: "center" }}
                >
                  <label
                    htmlFor="newPassword"
                    className="form-label"
                    style={{ width: "200px" }}
                  >
                    New Password
                  </label>
                  <div
                    style={{
                      border: "1px solid #ced4da",
                      display: "flex",
                      alignItems: "center",
                      width: "100%",
                    }}
                  >
                    <input
                      type={showPassword ? "text" : "password"}
                      className="form-control mx-3"
                      id="newPassword"
                      name="newPassword"
                      minLength={5}
                      value={newCredentials.newPassword}
                      onChange={(e) => onChange(e, "newPassword")}
                      style={{ outline: "none", border: 0 }}
                      required
                    />
                    <i
                      className={
                        showPassword
                          ? "fas fa-eye-slash mx-2"
                          : "fas fa-eye mx-2"
                      }
                      title={showPassword ? "Hide New Password" : "Show New Password"}
                      onClick={togglePasswordVisibilty}
                    ></i>
                  </div>
                </div>
              </div>

              <div className="mb-3">
                <div
                  className="pass-wrapper"
                  style={{ display: "flex", alignItems: "center" }}
                >
                  <label
                    htmlFor="confmNewPassword"
                    className="form-label"
                    style={{ width: "200px" }}
                  >
                    Confirm New Password
                  </label>
                  <div
                    style={{
                      border: "1px solid #ced4da",
                      display: "flex",
                      alignItems: "center",
                      width: "100%",
                    }}
                  >
                    <input
                      type={showConfmPassword ? "text" : "password"}
                      className="form-control mx-3"
                      id="confmNewPassword"
                      name="confmNewPassword"
                      value={newCredentials.confmNewPassword}
                      onChange={(e) => onChange(e, "confmNewPassword")}
                      minLength={5}
                      required
                      style={{ border: 0, outline: "none" }}
                    />
                    <i
                      className={
                        showConfmPassword
                          ? "fas fa-eye-slash mx-2"
                          : "fas fa-eye mx-2"
                      }
                      title={
                        showConfmPassword
                          ? "Hide Confirmed NewPassword"
                          : "Show Confirmed NewPassword"
                      }
                      onClick={toggleConfmPasswordVisibilty}
                    ></i>
                  </div>
                </div>
              </div>

              <div className="d-grid gap-2 my-4 col-6 mx-auto">
                <button
                  type="submit"
                  className="btn btn-primary col-6 m-auto my-2"
                >
                  Change Password
                </button>
              </div>
              <hr />
              <div className="mb-3 text-center">
                <div id="emailHelp" className="form-text center my-3">
                  Want to go back ?
                </div>
                <div className="d-grid gap-2 my-3 col-6 mx-auto">
                  <button
                    onClick={backToForgot}
                    className="btn btn-primary col-6 m-auto"
                  >
                    Back
                  </button>
                </div>
              </div>
            </form>
          </div>
        </div>
      </div>
    </>
  );
};

export default ChangePasswordPage;

后端代码

const express = require("express");
const router = express.Router();
const bcrypt = require("bcryptjs");
const jwt = require("jsonwebtoken");
const JWT_SECRET = "mohitisagood$boy";
const User = require("../models/User");

router.put("/", async (req, res) => {
  const { email, newPassword, confmNewPassword } = req.body;

  let success = false;

  try {
    //hashing the new password
    const salt = await bcrypt.genSalt(10);
    const secPass = await bcrypt.hash(newPassword, salt);

    //if newpassword does not matche swoth confirmPassword
    if (newPassword !== confmNewPassword) {
      res.status(400).json({ success, error: "Both password did not match !" });
    }

    //updating password
    let user = await User.findOneAndUpdate(
      { email: email },
      { $set: { password: secPass } },
      { returnOriginal: false }
    );

    if (!user) {
      res.status(400).json({ success, error: "Email does not exists !" });
    }

    //console.log(user);

    const payload = {
      user: {
        id: user.id,
      },
    };

    const authToken = jwt.sign(payload, JWT_SECRET);

    success = true;

    res.json({ success, authToken, user });
  } catch (error) {
    console.log(error.message);
    res.status(500).send("Internal Server Error");
  }
});

module.exports = router;

我已经在前端安慰了newCredentials,它给了这个

然后在前端代码中的console.log(json) 行之后不起作用。这意味着错误仅出现在fetch 部分。

请用你的知识解决问题。

【问题讨论】:

  • 在 UI 上输入

标签: javascript html reactjs api fetch


【解决方案1】:

我通过添加标题更正了代码

const handleSubmit = async (e) => {
    e.preventDefault();
    const response = await fetch("http://localhost:5000/api/changePassword",{
      method:"PUT",
      content: "application/json",
      body: JSON.stringify({
        email: newCredentials.email,
        newPassword: newCredentials.newPassword,
        confmNewPassword: newCredentials.confmNewPassword,
      }),
    });

【讨论】:

    【解决方案2】:

    删除JSON.stringify

    const response = await fetch("http://localhost:5000/api/changePassword", {
        method: "PUT",
        headers: {
            Accept: "application/json",
        },
        body: {
            email: newCredentials.email,
            newPassword: newCredentials.newPassword,
            confmNewPassword: newCredentials.confmNewPassword,
        }
    });
    

    【讨论】:

    • 不工作,仍然显示同样的错误。 @Narendra Chouhan
    • 尝试在 fetch api 调用中添加标头,请检查更新后的代码@MohitMaroliyaB17CS036
    • 好的,但在我添加标题之前。它显示错误Cannot set headers after they are sent to the client
    • 您的后端API正在发送两次res,尝试调试或注释所有res并只保留一个res。发送()
    • 尝试在您发送的回复前面添加return res.status(400).json()“return”@MohitMaroliyaB17CS036
    猜你喜欢
    • 2019-05-20
    • 2021-05-05
    • 2019-05-31
    • 2022-01-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-11-25
    相关资源
    最近更新 更多