简体   繁体   中英

400 BAD REQUEST when POST using Axios in React with Nodejs/Express

I use Axios with React to use POST method to my Nodejs server. The first time I tried it gave me an error regarding CORS policy. And I have added the header to it but still it gives me status code of 400 mentioning this:

xhr.js:166 POST http://localhost:3000/api/user/register 400 (Bad Request)
dispatchXhrRequest  @   xhr.js:166
xhrAdapter  @   xhr.js:16
dispatchRequest @   dispatchRequest.js:49
Promise.then (async)        
request @   Axios.js:56
wrap    @   bind.js:11
handleFormSubmit    @   Register.js:21
onClick @   Register.js:69
callCallback    @   react-dom.development.js:363
invokeGuardedCallbackDev    @   react-dom.development.js:412
invokeGuardedCallback   @   react-dom.development.js:465
invokeGuardedCallbackAndCatchFirstError @   react-dom.development.js:480
executeDispatch @   react-dom.development.js:613
executeDispatchesInOrder    @   react-dom.development.js:638
executeDispatchesAndRelease @   react-dom.development.js:743
executeDispatchesAndReleaseTopLevel @   react-dom.development.js:752
forEachAccumulated  @   react-dom.development.js:724
runEventsInBatch    @   react-dom.development.js:769
runExtractedPluginEventsInBatch @   react-dom.development.js:915
handleTopLevel  @   react-dom.development.js:5866
batchedEventUpdates$1   @   react-dom.development.js:24314
batchedEventUpdates @   react-dom.development.js:1460
dispatchEventForPluginEventSystem   @   react-dom.development.js:5966
attemptToDispatchEvent  @   react-dom.development.js:6083
dispatchEvent   @   react-dom.development.js:5986
unstable_runWithPriority    @   scheduler.development.js:818
runWithPriority$2   @   react-dom.development.js:12259
discreteUpdates$1   @   react-dom.development.js:24331
discreteUpdates @   react-dom.development.js:1485
dispatchDiscreteEvent   @   react-dom.development.js:5949





Error: Request failed with status code 400
    at createError (createError.js:17)
    at settle (settle.js:19)
    at XMLHttpRequest.handleLoad (xhr.js:60)


I was using JWT for my Auth which I wrote in Nodejs - runs on port 5000
React - runs on port 3000
I've my some othe features written in PHP - runs on port 8000

Here, when I used React Axios with PHP it worked fine after satisfying the CORS policy. But when I did it to Nodejs I get this error. Nodejs Auth code works fine, when I tried with POSTMAN.

Here's my React code which runs on port 3000

import React, { Component } from 'react'
import axios from 'axios'

class Register extends Component {
    constructor(props) {
        super(props)
        this.state = {
            name: "",
            email: "",
            password: "",
        }

    }

    handleFormSubmit(e) {
        e.preventDefault();


        const registerData = JSON.stringify(this.state);

        axios({
            method: 'POST',
            url: 'http://localhost:5000/api/user/register',
            headers: {
                'Content-Type': 'application/json',
                    },
            data: registerData,
        })
            .then(result => {
                console.log(registerData)
            })
            .catch(error => console.log(error))
    }
    render() {
        return (
            <div>
                Register
                <br/>
                <form action="#">
                    <label>Full Name</label><br/>
                    <input
                        type='text'
                        id='name'
                        name='name'
                        value={this.props.name}
                        onChange={e => this.setState({ name: e.target.value })} />
                    <br />

                    <label>Email</label><br />
                    <input
                        type='text'
                        id='email'
                        name='email'
                        value={this.props.email}
                        onChange={e => this.setState({ email: e.target.value })} />
                    <br />

                    <label>Password</label><br />
                    <input
                        type='password'
                        id='password'
                        name='password'
                        value={this.props.password}
                        onChange={e => this.setState({ password: e.target.value })} />
                    <br />

                    <input
                        type='submit'
                        onClick={e => this.handleFormSubmit(e)} />
                    <br />
                </form>
            </div>
        )
    }
}

export default Register

This is the package.json I've on React:

{
  "name": "dontbuy",
  "version": "0.1.0",
  "private": true,
  "dependencies": {
    "axios": "^0.19.0",
    "react": "^16.10.0",
    "react-dom": "^16.10.0",
    "react-native": "^0.61.1",
    "react-native-web": "^0.11.7",
    "react-router-dom": "^5.1.1",
    "react-scripts": "3.1.2"
  },
  "scripts": {
    "start": "react-scripts start",
    "build": "react-scripts build",
    "test": "react-scripts test",
    "eject": "react-scripts eject"
  },
  "eslintConfig": {
    "extends": "react-app"
  },
  "browserslist": {
    "production": [
      ">0.2%",
      "not dead",
      "not op_mini all"
    ],
    "development": [
      "last 1 chrome version",
      "last 1 firefox version",
      "last 1 safari version"
    ]
  },
  "proxy": "http://localhost:5000"
}

And here's my Nodejs code which runs on port 5000: (All my routes has a prefix of api/user/* )

const router = require('express').Router();
const User = require('../model/User');
const bcrypt = require('bcryptjs');
const { registerValidation, loginValidation } = require('../validation')
const jwt = require('jsonwebtoken');

//API response
router.post('/register' , async (req, res) => {


    //validating the response
    const { error } = registerValidation(req.body);
    if(error){
        return res.status(400).send(error);
    }

    //Check the user is already in the db
    const emailExists = await User.findOne({email: req.body.email});
    if(emailExists){
        return res.status(400).json({"message" : "Email already exists"});
    }

    //Hashing the password
    const salt = await bcrypt.genSalt(10);
    const hashedPassword = await bcrypt.hash(req.body.password, salt);

    //Creating a new user
        const user = new User({
            name: req.body.name,
            email: req.body.email,
            password: hashedPassword,
        })
        try {
            const savedUser = await user.save();
            res.send({ user: user._id });
        } catch (err) {
            res.status(400).send(err);
        }  
})


//Login

router.post('/login', async (req, res) => {
    //validation
    const { error } =loginValidation(req.body);
    if(error){
        return res.status(400).send(error.details[0].message);
    }
    //check if the email is already exists
    const user = await User.findOne({ email: req.body.email });
    if (!user) {
        return res.status(400).json({"message": "Email or password is incorrect"});
    }
    const validPassword = await bcrypt.compare(req.body.password, user.password);
    //check if password is correct
    if(!validPassword) {
        return res.status(400).json({"message" :"Password is incorrect"});
    }
    //create and assign a token
    const token = jwt.sign({_id: user._id}, 'secretKey');
    res.header('auth-token', token).send(token);

    res.send('Logged in')
})


module.exports = router;

Late to answer back. It was some validation error which my React - frontend validation allowed to send the API request to my Node.js backend but validations stopped the request with a 400 Status Code. My bad that I didn't notice this blunt error for a long time. Thanks for all your time for responding.

Your server is running on 5000 and you are calling api from 3000. Change port number in url as under

axios({
            method: 'POST',
            url: 'http://localhost:5000/api/user/register',
            headers: {
                'Content-Type': 'application/json',
                    },
            data: registerData,
        })

Try to change return res.status(400).json({"message": "Email already exists"}) to this res.status(400).send({"message": "Email already exists"}))

and

localhost:3000 to localhost:5000

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM