ReactJS/Express Axios POST returns 404, works from Postman

时光毁灭记忆、已成空白 提交于 2021-02-08 05:34:41

问题


I have no idea what I'm doing wrong here. The POST method works from Postman, but doesn't work from the React frontend.

users.js (/api/users/login)

// @route   POST api/users/login
// @desc    Login user / Returning JWT Token
// @access  Public
router.post('/login', (req, res, next) => {
  const { errors, isValid } = validateLoginInput(req.body);

  // Check validation
  if (!isValid) {
    return res.status(400).json(errors);
  }

  const email = req.body.email;
  const password = req.body.password;

  // Find user by email
  User.findOne({ email }) // matching email: email
    .then(user => {
      if (!user) {
        errors.email = 'User not found';
        return res.status(404).json(errors);
      }

    // Check Password
    bcrypt.compare(password, user.password)
      .then(isMatch => {
        if(isMatch) {

          // User matched. Create JWT payload
          const payload = {
            id: user.id
          } 

          // Sign Token
          jwt.sign(
            payload,
            keys.secretOrKey, 
            { expiresIn: 3600 }, 
            (err, token) => {
              res.json({
                success: true,
                token: 'Bearer ' + token
              });
          });
        } else {
          errors.password = 'Password incorrect'
          return res.status(400).json(errors);
        }
    });
  }); 
});

loginUser() function:

export const loginUser = userData => dispatch => {
  axios
    .post("/api/users/login", userData)
    .then(res => {
      // Save to localStorage
      const { token } = res.data;
      // Set token to localStorage
      localStorage.setItem("jwtToken", token); // only stores strings
      // Set token to Auth header
      setAuthToken(token);
      // Decode token to get user data
      const decoded = jwt_decode(token);
      // Set current user
      dispatch(setCurrentUser(decoded));
    })
    .catch(err =>
      dispatch({
        type: GET_ERRORS,
        payload: err.response.data
      })
    );
};

onSubmit() function in React component:

  onSubmit(e) {
    e.preventDefault();

    const userData = {
      email: this.state.email,
      password: this.state.password
    }

    this.props.loginUser(userData);
  }

Network:

Request URL: http://localhost:3000/api/users/login
Request Method: POST
Status Code: 404 Not Found
Remote Address: 127.0.0.1:3000
Referrer Policy: no-referrer-when-downgrade
Connection: keep-alive
Content-Length: 155
Content-Security-Policy: default-src 'self'
Content-Type: text/html; charset=utf-8
Date: Mon, 16 Jul 2018 01:53:03 GMT
Vary: Accept-Encoding
X-Content-Type-Options: nosniff
X-Powered-By: Express
Accept: application/json, text/plain, */*
Accept-Encoding: gzip, deflate, br
Accept-Language: en-US,en;q=0.9
Connection: keep-alive
Content-Length: 46
Content-Type: application/json;charset=UTF-8
Cookie: io=VtWk-hb742jVakwrAAAE; PHPSESSID=ige5g7257th8hiksjomg2khouu; i18next=en; connect.sid=s%3Aq6FkEveJbDYoKTy386QESFBxGaW8MjKd.qSBAkm2t23Ww4ZtHtcs7%2F1e5tDn528i0C6Hv7U3PwI0
Host: localhost:3000
Origin: http://localhost:3000
Referer: http://localhost:3000/login
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/67.0.3396.99 Safari/537.36
{email: "admin@gmail.com", password: "admin"}
email
:
"admin@gmail.com"
password
:
"admin"

The port on server.js:

// Initializint the port
const port = process.env.PORT || 5000;

app.listen(port, () => console.log(`Server running on port ${port}`));

I checked some similar issues here, and most of them were related to headers. In my case, the headers are application/json, so I don't think the problem is there. No problems hitting the endpoint through Postman.


回答1:


Your react app is running on a different port than your backend app. create-react-app runs on port 3000 and as you've stated your backend is running on port 5000.

When your client side app is making a request to the server, its actually making a request to port 3000 as you can see here.

Request URL: http://localhost:3000/api/users/login

It's doing so because you never specified the origin url in your request as you can see here post("/api/users/login", userData), and in that case it defaults to the same port the request came from which is port 3000, and port 3000 does not in fact have the url you requested.

You can solve this by either including the origin url in the request, or by adding a proxy to the react app package.json as you can here.

https://github.com/facebook/create-react-app/blob/master/packages/react-scripts/template/README.md#proxying-api-requests-in-development



来源:https://stackoverflow.com/questions/51353658/reactjs-express-axios-post-returns-404-works-from-postman

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!