这是服务器的响应,当我发送 404 状态码和消息时,它不会在客户端显示消息:
我正在使用 MERN 堆栈开发简单的用户身份验证/注册应用程序。 以下代码与邮递员一起工作正常,但是当从客户端调用时,即使我已经在服务器端验证了所有前端数据,也会给出错误 400 错误请求。 此外,还添加了用于身份验证的标头。
这是用于注册和登录的 ReactJs 代码。 注册-
import React,{useState} from 'react';
import { makeStyles,createMuiTheme, MuiThemeProvider } from '@material-ui/core/styles';
import Paper from '@material-ui/core/Paper';
import TextField from '@material-ui/core/TextField';
import Button from '@material-ui/core/Button'
import { Typography} from "@material-ui/core";
import axios from 'axios';
const API_URL = "http://localhost:2000/"
const styles = {
button: {
margin: 15,
color: '#AC3B61',
background: '#ffffff',
fontWeight: 'bold',
},
floatingLabelFocusStyle: {
color: "#F9A257"
},
};
const theme = createMuiTheme({
palette: {
primary: {
main: '#EDF5E1'
},
secondary: {
main: '#EDF5E1'
},
}
})
const useStyles = makeStyles((theme) => ({
root: {
display: 'flex',
flexGrow: 1,
justifyContent: 'center',
},
control: {
padding: theme.spacing(2),
width: theme.spacing(50),
height: theme.spacing(50),
marginTop: theme.spacing(5),
background: '#AC3B61',
color: '#ffffff ',
height: 500,
borderRadius:"8%"
},
}));
const SignUp = (props) => {
const classes = useStyles();
const [state,setState]=useState({
firstname:"",
lastname:"",
email:"",
password:"",
con_password:""
});
const handleChange=(e)=>{
setState({
...state,[e.target.id]:e.target.value
})
}
const handleSubmit=(e)=>{
const profile={}
profile.firstname = state.firstname;
profile.lastname = state.lastname;
profile.email = state.email;
profile.password = state.password;
profile.con_password = state.con_password;
axios.post(`${API_URL}register/profile`,profile,{
headers:{
Accept:"application/json",
"Content-Type":"application/json"
}
})
.then((res)=>console.log(res.status))
.catch((err)=>console.log(err));
}
return (
<div className={classes.root}>
<MuiThemeProvider theme={theme}>
<form onSubmit={handleSubmit} autoComplete="off">
<Paper variant="standard" className={classes.control} elevation={15}>
<Typography variant="h4" gutterBottom>
Sign-Up
</Typography>
<TextField id="firstname" label="First Name" variant="standard" onChange={handleChange} required={true}/>
<br/><br/>
<TextField id="lastname" label="Last Name" variant="standard" onChange={handleChange} required={true}/>
<br/><br/>
<TextField id="email" label="Email" variant="standard" type="email" onChange={handleChange} required={true}/>
<br/><br/>
<TextField id="password" label="Password" variant="standard" type="password" onChange={handleChange} required={true}/>
<br/><br/>
<TextField id="con_password" label="Confirm-Password" variant="standard" type="password" onChange={handleChange} required={true}/>
<br/><br/>
<Button
onClick={handleSubmit}
style={styles.button}>Submit</Button>
</Paper>
</form>
</MuiThemeProvider>
</div>
);
}
export default SignUp;
登录-
import React,{useState} from 'react';
import { makeStyles,createMuiTheme, MuiThemeProvider } from '@material-ui/core/styles';
import Paper from '@material-ui/core/Paper';
import TextField from '@material-ui/core/TextField';
import Button from '@material-ui/core/Button'
import { Typography} from "@material-ui/core";
import axios from 'axios';
const API_URL = "http://localhost:2000/"
const styles = {
button: {
margin: 15,
color: '#AC3B61',
background: '#ffffff',
fontWeight: 'bold',
},
floatingLabelFocusStyle: {
color: "#F9A257"
},
};
const theme = createMuiTheme({
palette: {
primary: {
main: '#EDF5E1'
},
secondary: {
main: '#EDF5E1'
},
}
})
const useStyles = makeStyles((theme) => ({
root: {
display: 'flex',
flexGrow: 1,
justifyContent: 'center',
},
control: {
padding: theme.spacing(2),
width: theme.spacing(50),
height: theme.spacing(50),
marginTop: theme.spacing(5),
background: '#AC3B61',
color: '#ffffff ',
height: 300,
borderRadius:"8%"
},
}));
const LogIn = (props) => {
const classes = useStyles();
const [state, setState] = useState({
email:" ",
password:" "
});
const handleChange = (e) =>{
setState({
...state,[e.target.id]:e.target.value
});
}
const handleSubmit=(e)=>{
e.preventDefault();
let profile={}
profile.email = state.email;
profile.password = state.password;
axios.post(`${API_URL}login/profile`,profile,{
headers:{
Accept:"application/json",
"Content-Type":"application/json"
}
})
.then((res)=>{
console.log(res.status)
props.history.push('/dashboard')
})
.catch(err=>console.log(err));
}
return (
<div className={classes.root}>
<MuiThemeProvider theme={theme}>
<form onSubmit={handleSubmit} autoComplete="off">
<Paper variant="outlined" className={classes.control} elevation={15}>
<Typography variant="h4" gutterBottom>
Log-In
</Typography>
<TextField id="email" label="Email" variant="standard" type="email"
onChange={handleChange}
required={true}
/>
<br/><br/>
<TextField id="password" label="Password" variant="standard" type="password"
onChange={handleChange}
required={true}
/>
<br/><br/>
<Button
onClick={handleSubmit}
style={styles.button}>Submit</Button>
</Paper>
</form>
</MuiThemeProvider>
</div>
);
}
export default LogIn;
这是后端服务器 -
index.js
const express = require('express');
const mongoose = require('mongoose');
const Router = require('./routes/Router');
const mongoURI = require('./config/Keys').mongoURI;
const bodyParser = require('body-parser');
const cors = require('cors');
//initiated app()
const app = express();
//middleware for database / mongodB atlas
try {
mongoose.connect( mongoURI, {useNewUrlParser: true, useUnifiedTopology: true}, () =>
console.log('connected to the database successfully'));
}catch (error) {
console.log("could not connect");
}
//global promise overriding
mongoose.Promise = global.Promise;
//bodypaerser middleware
app.use(bodyParser.json());
//cors middleware
app.use(cors());
//handling requests middleware
app.use('/',Router);
//error middleware
app.use((err,req,res,next)=>{
//console.log(err.message);
res.status(422).send({
err:err.message
})
});
const port = 2000 || process.env.port;
app.listen(port,()=>{
console.log(`connected to the port ${port} successfully`);
});
这是其余的 API -
const express = require('express');
const Router = express.Router();
const ProfileModel = require('../models/profilemodel');
const bcrypt = require("bcryptjs");
const jwt = require('jsonwebtoken');
const { RegisterValidator,LoginValidator } = require('../validator/ProfileValidator');
const secrete = require('../config/Keys').secrete;
//handling cors errors
Router.use((req,res,next)=>{
res.setHeader("Access-Control-Allow-Origin","*");
res.setHeader(
"Access-Control-Allow-Headers",
"Origin,X-Requested-With,Content-Tpe,Accept,Authorization"
);
res.setHeader('Access-Control-Allow-Methods','GET,POST');
//res.status(200).json({msg:"preflight request was made"});
if (req.method === 'OPTIONS') {
return res.sendStatus(200); // to deal with chrome sending an extra options request
}
next();
})
//register request handler
Router.post('/register/profile',(req,res,next)=>{
console.log('register req was made');
//validating registration
const {msg,isValid} = RegisterValidator(req.body);
if(!isValid)
{
return res.status(404).json({msg:msg});
}
ProfileModel.findOne({email:req.body.email})
.then((profile)=>{
if(profile)
{
return res.status(401).json({msg:'user already exist'});
}
const newProfile = new ProfileModel({
firstname:req.body.firstname,
lastname:req.body.lastname,
email:req.body.email,
password:req.body.password
})
//hash the passwords before saving to database
bcrypt.genSalt(10,(err,salt)=>{
bcrypt.hash(newProfile.password,salt,(err,hash)=>{
if(err)
{
throw err;
}
newProfile.password = hash;
newProfile.save()
.then((user)=>{
//generatung a token
const token = jwt.sign({id:user._id},secrete,{
expiresIn:86400 //24 hrs in seconds
});
res.status(200).send({auth:true,token});
})
.catch(err => console.log(err));
});
});
})
});
//login req handler
Router.post('/login/profile',(req,res,next)=>{
console.log('login req was made');
//validating email
const {msg,isValid} = LoginValidator(req.body);
if(!isValid)
{
return res.status(404).json({msg:msg});
}
const email = req.body.email;
const password = req.body.password;
ProfileModel.findOne({email})
.then((user)=>{
if(!user)
{
return res.status(404).json({emailnotfound:'user doe not exist'})
}
//compare passwords
bcrypt.compare(password,user.password)
.then((isMatch)=>{
if(!isMatch)
{
return res.status(400).json({incorrectpassword:'please enter the correct password'})
}
const token = jwt.sign({id:user._id},secrete,{
expiresIn:86400 //24 hrs
});
return res.status(200).send({auth:true,token});
})
.catch((err)=>console.log(err));
})
.catch((err)=>console.log(err));
});
//sending the token to client
Router.get('/verifytoken',(req,res)=>{
const token = req.headers['token'];
//console.log(req.headers);
if(!token) return res.status(401).send({auth:false,token:'no token'});
jwt.verify(token,secrete,(err,decoded)=>{
if(err) return res.status(500).send({auth:false,token:'failed to authenticate'});
// res.status(200).send(decoded);
ProfileModel.findById(decoded.id,{password:0}) //projection
.then((user)=>{
if(!user) return res.status(401).send("'no user found");
return res.status(201).send(user);
})
});
})
module.exports = Router;
axios.post(`${API_URL}login/profile`,JSON.stringify(profile),{
headers:{
Accept:"application/json",
"Content-Type":"application/json"
}
})
请尝试用
JSON.stringify()
包装您发布的数据