岗位http://localhost:3000/api/users404(未找到)



MERN Stack/REDUX-试图将注册/注册的用户数据从我的React应用程序发送到我的mongoDB中,但不断收到404错误,让我知道该页面不存在。我以前可以在以前的应用程序上连接它,但现在遇到了问题。

Server.js文件:

const express = require("express");
const connectDB = require("./config/db");
const path = require("path");
const bodyParser = require("body-parser");
const app = express();
//Connecting to the DB \
connectDB();
// Middleware Init\
app.use(express.json({ extended: false }));
app.use(bodyParser.json());
// Routes \
app.use("/api/users", require("./routes/users"));
app.use("/api/auth", require("./routes/auth"));
// Static assets if in production (deployment purposes) \
if (process.env.NODE_ENV === "production") {
// Set static folder \
app.use(express.static("client/build"));
app.get("*", (req, res) => {
res.sendFile(path.join(__dirname, "client", "build", "index.html"));
});
}
const PORT = process.env.PORT || 5000;
app.listen(PORT, () => console.log(`Server started on port ${PORT}`));


用户路线:

const express = require("express");
const router = express.Router();
const { check, validationResult } = require("express-validator");
const bcrypt = require("bcryptjs");
const jwt = require("jsonwebtoken");
const config = require("config");
const auth = require("../middleware/auth");
//importing User Schema \
const User = require("../models/User");
// @route   POST api/users
// @desc    Register user
// @access  Public
router.post(
"/", [
check("firstname", "First Name is Required").not().isEmpty(),
check("lastname", "Last Name is Required").not().isEmpty(),
check("email", "Email is Required").isEmail(),
check(
"password",
"Please enter a password with 5 or more character"
).isLength({ min: 5 }),
],
async(req, res) => {
const errors = validationResult(req);
if (!errors.isEmpty()) {
return res.status(400).json({ errors: errors.array() });
}
// just deconstruct firstname, lastname, email, and password, isAdmin from req.body \
const { firstname, lastname, email, password, isAdmin } = req.body;
try {
// see if user exists \
let user = await User.findOne({ email });
if (user) {
return res
.status(400)
.json({ errors: [{ msg: "User already exists" }] });
}
user = new User({
firstname,
lastname,
email,
password,
isAdmin,
});
// Encrypt password \
const salt = await bcrypt.genSalt(10);
user.password = await bcrypt.hash(password, salt);
await user.save();
// Return jsonwebtoken
const payload = {
user: {
id: user.id,
},
};
// Login good for 1 hour \
jwt.sign(
payload,
config.get("jwtSecret"), { expiresIn: 36000 },
(err, token) => {
if (err) throw err;
res.json({ token });
}
);
} catch (err) {
console.error(err.message);
res.status(500).send("Server Error");
}
}
);
// @route   PUT api/users/address
// @desc    Add/edit address
// @access  Private
router.put(
"/address", [
auth, [
check("street", "Street is required").not().isEmpty(),
check("country", "Country is required").not().isEmpty(),
check("city", "City is required").not().isEmpty(),
check("state", "State/Province is required").not().isEmpty(),
check("zipcode", "Zip/Postal Code is required").not().isEmpty(),
],
],
async(req, res) => {
const errors = validationResult(req);
if (!errors.isEmpty()) {
return res.status(400).json({ errors: errors.array() });
}
const { street, country, city, state, zipcode } = req.body;
const newAddress = {
street,
country,
city,
state,
zipcode,
};
try {
// look for the user with the id and then update the address
await User.updateOne({ _id: req.user.id }, {
$set: {
address: newAddress,
},
});
res.json({ msg: "Successfully saved your address." });
} catch (err) {
console.error(err.message);
res.status(500).send("Server Error");
}
}
);
module.exports = router;

数据库配置(DB.js(:

const mongoose = require("mongoose");
const config = require("config");
const db = config.get("mongoURI");
const connectDB = async() => {
try {
await mongoose.connect(db, {
useNewUrlParser: true,
useCreateIndex: true,
useFindAndModify: false,
useUnifiedTopology: true,
});
console.log("MongoDB Connected!..");
} catch (err) {
console.error(err.message);
//exit process with failure\
process.exit(1);
}
};
module.exports = connectDB;

DB配置(默认.json(

{
"mongoURI": "mongodb+srv://AJ****:*********@sustdropclust.zcc0v.mongodb.net/*******? 
retryWrites=true&w=majority",
"jwtSecret": "**********"

}

中间件:

const jwt = require("jsonwebtoken");
const config = require("config");
module.exports = function(req, res, next) {
// Get token from header \
const token = req.header("x-auth-token");
// check if no token \
if (!token) {
return res.status(401).json({ msg: "No token, auth denied" });
}
// Verify token \
try {
const decoded = jwt.verify(token, config.get("jwtSecret"));
req.user = decoded.user;
next();
} catch (err) {
res.status(401).json({ msg: "Token not valid" });
}
};

Redux操作(auth.js(:

import axios from "axios";
import { setAlert } from "./alert";
import {
REGISTER_SUCCESS,
REGISTER_FAIL,
USER_LOADED,
AUTH_ERROR,
LOGIN_SUCCESS,
LOGIN_FAIL,
LOGOUT,
MAKE_ADMIN,
RESET_RECENT_ORDERS_LOADING,
} from "./types";
import setAuthToken from "../utilities/setAuthToken";
// Load User
export const loadUser = () => async(dispatch) => {
if (localStorage.token) {
setAuthToken(localStorage.token);
}
try {
const res = await axios.get("/api/auth");
if (res.data.isAdmin) {
dispatch({ type: MAKE_ADMIN });
}
dispatch({
type: USER_LOADED,
payload: res.data,
});
} catch (err) {
dispatch({
type: AUTH_ERROR,
});
}
};
// Register User
export const register = ({ firstname, lastname, email, password }) => async(
dispatch
) => {
const config = {
headers: {
"Content-Type": "application/json",
},
};
const body = JSON.stringify({ firstname, lastname, email, password });
try {
const res = await axios.post("/api/users", body, config);
dispatch({
type: REGISTER_SUCCESS,
payload: res.data,
});
dispatch(loadUser());
dispatch(setAlert("Registration is successful", "success"));
} catch (err) {
const errors = err.response.data.errors;
if (errors) {
errors.forEach((error) => dispatch(setAlert(error.msg, "danger")));
}
dispatch({
type: REGISTER_FAIL,
});
}
};
// Login User
export const login = (email, password) => async(dispatch) => {
const config = {
headers: {
"Content-Type": "application/json",
},
};
const body = JSON.stringify({ email, password });
try {
const res = await axios.post("/api/auth", body, config);
dispatch({
type: LOGIN_SUCCESS,
payload: res.data,
});
dispatch(setAlert("Welcome! Login Successful!", "success"));
dispatch(loadUser());
} catch (err) {
const errors = err.response.data.errors;
if (errors) {
errors.forEach((error) => dispatch(setAlert(error.msg, "danger")));
}
dispatch({
type: LOGIN_FAIL,
});
}
};
// Logout / Clear Profile
export const logout = () => (dispatch) => {
dispatch({ type: LOGOUT });
// Resets the loading for recent orders incase another user logs in without refreshing the page
dispatch({ type: RESET_RECENT_ORDERS_LOADING });
};
// Add or Edit Address - Add address if it is null, edit it otherwise.
export const addAddress = ({ formData }) => async(dispatch) => {
const config = {
headers: {
"Content-Type": "application/json",
},
};
try {
const res = await axios.put("/api/users/address", formData, config);
dispatch(loadUser());
dispatch(setAlert(res.data.msg, "success"));
} catch (err) {
const errors = err.response.data.errors;
if (errors) {
errors.forEach((error) => dispatch(setAlert(error.msg, "danger")));
}
}
};

Redux Reducers(auth.js(:

import {
REGISTER_SUCCESS,
REGISTER_FAIL,
USER_LOADED,
AUTH_ERROR,
LOGIN_SUCCESS,
LOGIN_FAIL,
LOGOUT,
MAKE_ADMIN,
} from "../actions/types";
//add isAdmin later to authenticate if the current user is an admin (maybe just check user.isAdmin 
once we get the user and put it in the state)
const initialState = {
token: localStorage.getItem("token"),
isAuthenticated: false,
loading: true,
user: null,
isAdmin: false,
};
export default function(state = initialState, action) {
const { type, payload } = action;
switch (type) {
case USER_LOADED:
return {
...state,
isAuthenticated: true,
loading: false,
user: payload,
};
case REGISTER_SUCCESS:
case LOGIN_SUCCESS:
localStorage.setItem("token", payload.token);
return {
...state,
...payload,
isAuthenticated: true,
loading: false,
};
case REGISTER_FAIL:
case LOGIN_FAIL:
case AUTH_ERROR:
case LOGOUT:
localStorage.removeItem("token");
return {
...state,
token: null,
isAuthenticated: false,
loading: false,
isAdmin: false,
user: null,
};
case MAKE_ADMIN:
return {
...state,
isAdmin: true,
};
default:
return state;
}
}

注册页面(register.js(:

import React, { useState } from "react";
import { Link, Redirect } from "react-router-dom";
import { connect } from "react-redux";
import { setAlert } from "../../actions/alert";
import { register } from "../../actions/auth";
import PropTypes from "prop-types";
import "./Login.css";
const Register = ({ setAlert, register, isAuthenticated }) => {
const [formData, setFormData] = useState({
firstname: "",
lastname: "",
email: "",
password: "",
password2: "",
});
const { firstname, lastname, email, password, password2 } = formData;
// it changes the value of the target every keystroke
const onChange = (e) =>
setFormData({...formData, [e.target.name]: e.target.value });
const onSubmit = (e) => {
e.preventDefault();
if (password !== password2) {
setAlert("Passwords do not match", "danger");
} else {
register({ firstname, lastname, email, password });
}
};
// Redirects to /account after a successful registration
if (isAuthenticated) {
return <Redirect to = "/account" / > ;
}
return ( 
<div className = "wrapper-register" >
<h1 className = "large text-dark" > create an account < /h1>
<form onSubmit = {(e) => onSubmit(e)}>
<div className = "form-group" >
<label htmlFor = "firstname" > first name < /label> 
<input className = "form-control" type = "text" name = "firstname" value = { firstname } onChange = {(e) => onChange(e)}/> 
</div> 
<div className = "form-group" >
<label htmlFor = "lastname" > last name </label> 
<input className = "form-control" type = "text" name = "lastname" value = { lastname } onChange = {(e) => onChange(e)}/> 
</div> 
<div className = "form-group" >
<label htmlFor = "email" > email </label> 
<input className = "form-control" type = "email" name = "email" value = { email } onChange = {(e) => onChange(e)}/> 
</div> 
<div className = "form-group" >
<label htmlFor = "password" > password </label> 
<input className = "form-control" type = "password" name = "password" value = { password } onChange = {(e) => onChange(e)} minLength = "6" />
</div> 
<div className = "form-group" >
<label htmlFor = "password" > confirm password < /label> < input className = "form-control" type = "password" name = "password2" value = { password2 } onChange = {(e) => onChange(e)}minLength = "6" />
</div> 
<div className = "register-button" >
<input type = "submit" className = "btn btn-dark btn-block" value = "Register" />
</div> 
</form > 
<p>Already have an account ? < Link to = "/account/login" > Sign In </Link> </p> 
</div>
);
};
Register.propTypes = {
setAlert: PropTypes.func.isRequired,
register: PropTypes.func.isRequired,
};
const mapStateToProps = (state) => ({
isAuthenticated: state.auth.isAuthenticated,
});
export default connect(mapStateToProps, { setAlert, register })(Register);

我注意到您正在端口5000上运行服务器,我想这可能是导致错误的原因,因为您正在向端口3000发送POST请求。除非您指定了进程中的端口。env.port为3000。

想明白了。当你通过create react app cli创建一个react app时,你必须在package.json中指定并设置你的代理,就像这样"代理":"http://localhost:4000"。这样,当您在开发中获取("/api/signup"(时,开发服务器将识别出它不是静态资产,并将您的请求代理到http://localhost:4000/api/signup

在Redux Actions(auth.js(中,您可以在axios默认值中设置基本URL路径(仅在导入之后(。

window.axios.defaults.baseURL = (process.env.NODE_ENV !== 'production') ? 'your production server url' : 'http://localhost:5000/';

重新启动前端。如果你正在使用react,请停止它的运行,然后重新运行!问题解决了!!!

相关内容

  • 没有找到相关文章

最新更新