【问题标题】:Post localhost:3000/api/users 404 not found发布 localhost:3000/api/users 404 未找到
【发布时间】:2021-05-11 01:22:03
【问题描述】:

尝试设置会弹出错误的身份验证,该错误会根据尝试注册时出现的错误而变化。无法弄清楚为什么我会收到此错误。任何帮助将不胜感激

我附上了一张错误图片和代码,以帮助弄清楚发生了什么。当密码不匹配时,我可以弹出警报,但对于没有姓名、没有电子邮件和没有密码的其他错误,我无法让它工作

Error

动作

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, email, 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, email, 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, email, 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', 'Please Include Valid Email').isEmail(),
    // check email has min 6 char
    check('password', 'Please enter a password with 6 Character minimum').isLength({ min: 6 })
  ],

  // 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 name, email, and password for ease of use
    const { name, email, 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,
        email,
        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,
        // 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')
  })

// 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('/', (req, 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 服务器是否在 3000 端口上运行?我认为它不是,因为这是反应开发服务器运行的地方。
  • 我的 api 在端口 5000 上运行,我不确定如何将请求从端口 3000 更改为端口 5000
  • axios.post('http://localhost:5000/api/users'

标签: javascript http-status-code-404 mern


【解决方案1】:

您的 API 服务器在此处的默认端口 5000 上运行。如果您没有提供 PORT=3000 作为环境变量,则服务器在端口 5000 上运行。

【讨论】:

  • 感谢您的帮助,我遇到了麻烦,因为如果我将端口切换到 3000,我的前端和后端都在同一个端口上运行。有没有办法让我更改发布请求的端口?
  • @LuisErnestoRivasVillacorta 没有理解您的问题。您想在不同于 3000 的端口上运行服务器吗?
【解决方案2】:

您的服务器端口是 5000 (localhost:5000),并且您的 axios 请求正在访问 localhost:3000。

您可以通过替换将您的快速端口更改为 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 上运行。

注意:您可以根据自己的喜好在任一端(服务器或前端)更改端口

【讨论】:

    猜你喜欢
    • 2021-03-11
    • 2022-09-28
    • 1970-01-01
    • 1970-01-01
    • 2018-11-22
    • 1970-01-01
    • 1970-01-01
    • 2016-08-06
    • 2021-09-14
    相关资源
    最近更新 更多