如何解决发布 localhost:3000/api/users 404 未找到
尝试设置身份验证会弹出错误,该错误会根据尝试注册时出现的错误而改变。无法弄清楚为什么我会收到此错误。任何帮助将不胜感激
我附上了一张错误图片和代码,以帮助弄清楚发生了什么。当密码不匹配时,我可以收到警报弹出,但我无法让它用于其他没有姓名、没有电子邮件和没有密码的错误
行动
import axios from 'axios'
import { setAlert } from './alert'
import { REGISTER_SUCCESS,REGISTER_FAIL } from './types'
export const register = ({ name,email,password }) => async dispatch => {
const config = {
headers: { 'Content-Type': 'application/json' }
}
const body = JSON.stringify({ name,password })
try {
const res = await axios.post('/api/users',body,config)
dispatch({
type: REGISTER_SUCCESS,payload: res.data
})
} catch (err) {
const errors = err.response.data.errors
if (errors) {
errors.forEach(error => dispatch(setAlert(error.msg,'danger')))
}
dispatch({
type: REGISTER_FAIL
})
}
}
警报
// bring in set types
import { SET_ALERT,REMOVE_ALERT } from '../actions/types'
// set initial state as empty
const initialState = []
// export fucntion that takes in that that is initial state and an action
export default function something (state = initialState,action) {
// destructure action
const { type,payload } = action
// evaluate actions based on their type
switch (type) {
// in case of set alert
case SET_ALERT:
// copy into array,alert that is given to us in state,and set alert with action.payload
return [...state,payload]
case REMOVE_ALERT:
// use filter to find a specific alert and see if alert id is NOT equal to the alert in the payload (filter through all alerts except the one that matches the payload)
return state.filter(alert => alert.id !== payload)
// default to simply returning the state
default:
return state
}
}
注册
import React,{ Fragment,useState } from 'react'
// bring in connect
import { connect } from 'react-redux'
// bring in setAlert
import { setAlert } from '../../actions/alert'
import { register } from '../../actions/auth'
// bring in proptypes
import PropTypes from 'prop-types'
const Register = ({ setAlert,register }) => {
// the object full of values is formData,function to update state(formData) is setform data
const [ formData,setFormData ] = useState({
// default state values
name: '',email: '',password: '',password2: ''
})
// destructure formData
const { name,password,password2 } = formData
// the on chage at the level of the individual form input will call the onChange function that will call setFormData which
// changes the value based on the name of the target and the value inputed to the target
const onChange = e => setFormData({ ...formData,[e.target.name]: e.target.value })
// on submit funciton arrow function
const onSubmit = e => {
// prevent lock
e.preventDefault()
// if password does not match password too,log error message the alert is the class for the styling
if (password !== password2) {
setAlert('passwords do not match','danger')
// if it does work,log the data in the state
} else {
register({ name,password })
}
}
// adding value={variable} asociates the variable with the current state,the on change causes the state to be updated
return (
<Fragment>
<h1> Registration </h1>
<p> Create your account </p>
<form onSubmit={e => onSubmit(e)}>
<div>
<input
type='text'
placeholder='Name'
name='name'
value={name}
onChange={e => onChange(e)}
/>
</div>
<div>
<input
type='email'
placeholder='Email Address'
name='email'
value={email}
onChange={e => onChange(e)}
/>
</div>
<div>
<input
type='password'
placeholder='Password'
name='password'
minLength='6'
value={password}
onChange={e => onChange(e)}
/>
</div>
<div>
<input
type='password'
placeholder='Confirm Password'
name='password2'
minLength='6'
value={password2}
onChange={e => onChange(e)}
/>
</div>
<div>
<input type='submit' value='Register' />
</div>
<p>
Already have an account?
<a href='/login' > Login </a>
</p>
</form>
</Fragment>
)
}
// proptype regis
Register.propTypes = {
setAlert: PropTypes.func.isRequired,register: PropTypes.func.isRequired
}
// export using connect the null is temporar and this lets us pass setAlert (actions we want to use from props) State,object with actions we want to use
export default connect(null,{ setAlert,register })(Register)
身份验证 API
// bring in express
const express = require('express')
// bring in router
const router = express.Router()
// Bring in middleware
const auth = require('../../middleware/auth')
// bring in user model
const User = require('../../models/Users')
// bring in validator
const { check,validationResult } = require('express-validator')
// Bring in JWT
const jwt = require('jsonwebtoken')
// Bring in secret
const config = require('config')
// Bring in Bcrypt
const bcrypt = require('bcryptjs')
// @Route: Get api/auth
// @Description: Test route
// @access: Public
// when using path api/auth/ send "auth route" response *add auth to make the route protected by middleware* make it asynch
router.get('/',auth,async (req,res) => {
// when accessing this get request
try {
// search user model by id and excldue the password
const user = await User.findById(req.user.id).select('-password')
// respond with the information taken from the database tied to the selected id
res.json(user)
// if unable to find by id
} catch (err) {
// log error
console.error(err.message)
// send error code 500 and server error dialogue
res.status(500).send('server error')
}
})
// @Route: Post api/auth
// @Description: Authenticate user and get token
// @access: Public
// get api/users/ will send response of user route
router.post(
'/',// adds secondary requirement of running checks
[
// check email is valid
check('email','Please Include Valid Email').isEmail(),// check email is present
check('password','Password is requried').exists()
],// asynch because is its what is commonly used
async (req,res) => {
// set errors to result from validation
const errors = validationResult(req)
// if not errors is empty
if (!errors.isEmpty()) {
// reutn the status 400 and an json array that shows the error.
return res.status(400).json({ errors: errors.array() })
}
// bring in user information,destructure req.body into email,and password for ease of use
const { email,password } = req.body
try {
// check if user exists
// look at response to find email
let user = await User.findOne({ email })
// if user is not found
if (!user) {
// send error status and show invalid crednetials
return res.status(400).json({ errors: [{ msg: 'Invalid Credentials' }] })
}
// check that password matches to the user by comparing the plain text password to the encrypted password
const isMatch = await bcrypt.compare(password,user.password)
// if it does not match then throw 400 status and show invalid credential message
if (!isMatch) {
// 400 response and jsonformat response of invalid credentials
return res.status(400).json({ errors: [{ Msg: 'Invalid crednetials ' }] })
}
// return jsonwebtoken
// create payload to use with jwt
const payload = {
// look at saved user
user: {
// pull out promised user.id
id: user.id
}
}
// jwt sign
// sign with payload and with jwttoken pulled from default.json
jwt.sign(
payload,// configures the jwt token
config.get('jwtSecret'),// expires in an hour
{ expiresIn: 3600 },// if an error
(err,token) => {
// throw the error
if (err) throw err
// response with the token
res.send({ token })
// console.log(token)
}
)
} catch (err) {
// console the error message
console.error(err.message)
// send 500 status with server error text
res.status(500).send('server error')
}
console.log('something was posted')
})
// export route to be used in other parts of the program
module.exports = router
用户路线
// brining in express
const express = require('express')
// bring in router
const router = express.Router()
// bring in validator
const { check,validationResult } = require('express-validator')
// bring in user model
const User = require('../../models/Users')
// Bring in Bcrypt
const bcrypt = require('bcryptjs')
// Bring in JWT
const jwt = require('jsonwebtoken')
// Bring in secret
const config = require('config')
// @Route: Get api/users
// @Description: Test route
// @access: Public
// get api/users/ will send response of user route
// router.get('/',(req,res) => res.send('User Route'))
// @Route: Post api/users
// @Description: Register User
// @access: Public
// get api/users/ will send response of user route
router.post('/',// adds secondary requirement of running checks
[
console.log('fart'),// check to make sure a name is present (that its not empty)
check('name','Name is required')
.not()
.isEmpty(),// check email is valid
check('email',// check email has min 6 char
check('password','Please enter a password with 6 Character minimum').isLength({ min: 6 })
],destructure req.body into name,and password for ease of use
const { name,password } = req.body
try {
// check if user exists
// look at response to find email
let user = await User.findOne({ email })
// if user already exists
if (user) {
// send error status and show user already exists message on client
return res.status(400).json({ errors: [{ msg: 'user already exists' }] })
}
// creates new user
user = new User({
name,password
})
// encrypt password
// generates salt from bycrpt promise
const salt = await bcrypt.genSalt(10)
// hashes password from newly created user and sets it to user.password
user.password = await bcrypt.hash(password,salt)
// save user use await since it leaves a promise
await user.save()
// return jsonwebtoken
// create payload to use with jwt
const payload = {
// look at saved user
user: {
// pull out promised user.id
id: user.id
}
}
// jwt sign
// sign with payload and with jwttoken pulled from default.json
jwt.sign(
payload,token) => {
// throw the error
if (err) throw err
// response with the token
res.send({ token })
// console.log(token)
}
)
} catch (err) {
// console the error message
console.error(err.message)
// send 500 status with server error text
res.status(500).send('server error')
}
console.log('something was posted')
})
// exporting the route to be used in other parts of the program
module.exports = router
服务器
/* requre express */
const express = require('express')
// require the connectDB function from db.js
const connectDB = require('./config/db')
/* create app that uses express */
const app = express()
// Connect Database
connectDB()
// initialize middleware
app.use(express.json({ extended: false }))
/* Default to port 5000 */
const PORT = process.env.PORT || 5000
/* Check to make sure API is running */
app.get('/',res) => res.send('API is Running'))
// Define routes
// make /api/users pertain to the user.js file so that we can use any routes that start with "/"
// when using /api/users we are really using './routes/api/users'
app.use('/api/users',require('./routes/api/users'))
// make /api/users pertain to the user.js file so that we can use any routes that start with "/"
// when using /api/users we are really using './routes/api/users'
app.use('/api/auth',require('./routes/api/auth'))
/* Listen for Server starting and output the port it started on */
app.listen(PORT,() => console.log(`server started on port ${PORT}`))
解决方法
您的 API 服务器在此处的默认端口 5000 上运行。如果您没有提供 PORT=3000 作为环境变量,则服务器在端口 5000 上运行。
,您的服务器端口是 5000 (localhost:5000),您的 axios 请求正在访问 localhost:3000。
您可以通过替换将您的 express 端口更改为 3000
const PORT = process.env.PORT || 5000
到
const PORT = process.env.PORT || 3000
在您的服务器文件中。
然后,打开您的 react-app 的 package.json
文件并从
"start": "react-scripts start"
到
"start": "PORT=8000 react-scripts start"
这将使您的 React 应用程序在端口 8000 上运行,而您的服务器在端口 3000 上运行。
注意:您可以在任一端(服务器或前端)根据自己的喜好更改端口
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。