Getting 404 (Not Found) on axios.delete()

孤者浪人 提交于 2021-01-28 14:17:45

问题


I'm trying to implement the delete functionality for my survey creation app.

I'm using MongoDB with mongoose for the database, node.js/Express for the backend server and React/Redux for the frontend side.

Although I think I set routing correctly, I get 404 (Not Found) on axios.delete().

The error says that http://localhost:3000/api/surveys/delete/{the-survey-id-here} is not found.

I have been reading the documentation of axios, Express, mongoose and other websites, however, nothing worked for me.

I tried the following things.

  • Use findByIdAndRemove() instead of deleteOne()
  • Pass surveyId in the action creator const response = await axios.delete("/api/surveys", data: { surveyId });
  • Use <a></a> instead of <button></button>

Here are my codes.

SurveyList.js (react component which has the delete button)

import { fetchSurveys, deleteSurvey } from '../../actions'

...

<div className="card-action">
  <a className="red-text text-accent-1">Yes: {survey.yes}</a>
  <a className="red-text text-accent-1">No: {survey.no}</a>
  <button
    className="btn-floating btn-small waves-effect waves-light red right"
    onClick={() => this.props.deleteSurvey(survey._id)}
  >
    <i className="material-icons">delete_forever</i>
  </button>
</div>

...

const mapStateToProps = ({ surveys }) => {
  return { surveys }
}

export default connect(
  mapStateToProps,
  { fetchSurveys, deleteSurvey }
)(SurveyList)

actions/index.js (action creator)

export const deleteSurvey = (surveyId) => async dispatch => {
  const response = await axios.delete(`/api/surveys/delete/${surveyId}`)

  dispatch({ type: FETCH_SURVEYS, payload: response.data })
}

surveyRoute.js (routing handler)

app.delete('/api/surveys/delete/:surveyId', async (req, res) => {
  await Survey.deleteOne({ _id: req.params.surveyId })

  const surveys = await Survey.find({ _user: req.user.id }).select({
    recipients: false
  })
  res.send(surveys)
})

server/index.js

const express = require('express')
const mongoose = require('mongoose')
const cookieSession = require('cookie-session')
const passport = require('passport')
const bodyParser = require('body-parser')
const keys = require('./config/keys')
require('./models/User')
require('./models/Survey')
require('./services/passport')

mongoose.connect(keys.mongoURI)

const app = express()

app.use(bodyParser.json())
app.use(
  cookieSession({
    maxAge: 30 * 24 * 60 * 60 * 1000, // milliseconds
    keys: [keys.cookieKey]
  })
)
app.use(passport.initialize())
app.use(passport.session())

require('./routes/authRoutes')(app)
require('./routes/billingRoutes')(app)
require('./routes/surveyRoutes')(app)

if(process.env.NODE_ENV === 'production'){
  app.use(express.static('client/build'))

  const path = require('path')
  app.get('*',(req, res) => {
    res.sendFile(path.resolve(__dirname, 'client', 'build', 'index.html'));
  })
}

const PORT = process.env.PORT || 5000
app.listen(PORT)

回答1:


In my case, leads/ is the end point. try your end point + survey id
With axios@^0.19.2

       axios
            .delete('/api/leads/' + id)
            .then(res => {
                dispatch({
                    type: DELETE_LEAD,
                    payload: id
                });



回答2:


So if I undestood correctly, you have a Expressjs App and a client app running on different ports, if so I think I found the issue

You are making ajax calls as if you had both frontend and backend running on the same server. Here are two possible solutions

  1. Change the address of the Axios delete action to point to the right server if you are planning to run the backend and frontend on different servers

    app.delete('http://localhost:5000/api/surveys/delete/:surveyId', async (req, res) => {
      await Survey.deleteOne({ _id: req.params.surveyId })
    
      const surveys = await Survey.find({ _user: req.user.id }).select({
        recipients: false
      })
      res.send(surveys)
    })
    

    Off course you have to change the address once you deploy it to production and enable CORS

  2. Build the client app for producion, this process will compile all css, js and html and save it to client/build folder as stated on line

    res.sendFile(path.resolve(__dirname, 'client', 'build', 'index.html'));
    

    This will cause the frontend and backend code to run on the same server




回答3:


Thank you very much for all answers and comments. The problem was the proxy. I am using http-proxy-middleware to handle requests between different ports in the dev environment. All comments about ports made me realize that I need to check the 'setupProxy.js' file. I modified the code inside the file as below and that fixed the problem.

setupProxy.js

const proxy = require('http-proxy-middleware')

module.exports = function(app) {
  app.use(proxy ('/auth/google', { target: 'http://localhost:5000' }))
  app.use(proxy ('/api/**', { target: 'http://localhost:5000' }))
}

Thank you very much again for all the answers and comments.




回答4:


CORS (Delete verb) must be enabled in your route middleware.

This thread may help you.



来源:https://stackoverflow.com/questions/55404279/getting-404-not-found-on-axios-delete

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!