简体   繁体   中英

Why express call my get route and not my put route?

I have the following route in my express application:

router.get('/edit/:id', (req, res)=> {
    let searchQuery = {_id : req.params.id};
    console.log(searchQuery)
    Address.findOne(searchQuery)
        .then(address => {
            res.render('myForm', {address:address});
        })
        .catch(err => {
            console.log(err);
        });

});

and my form is:

 <form action="/edit/<%= address.id %>?_method=put" method="POST">
      <input type="hidden" name="_method" value="PUT">
      <br>
      <input type="text" value="<%= address.name %>" name="name" class="form-control">
      <br>
      <input type="text" value="<%= address.email %>" name="email" class="form-control">
      <br>

      <button type="submit" class="btn btn-info btn-block mt-3">Update User</button>
  </form>

It works correctly, I can see the data getting form the mongodb into myForm. Now after I update some data in this form and click the udpdate button i get : Cannot POST /edit/62185a7efd51425bbf43e21a

Noting that I have the following route:

router.put('/edit/:id', (req, res)=> {
    let searchQuery = {_id : req.params.id};
    console.log(`searchQuery = ${searchQuery}`)
    Address.updateOne(searchQuery, {$set: {
        name: _.extend(name, req.body),
        email: req.body.email,

    }})
    .then(address => {
        res.redirect('/');
    })
    .catch(err => {
        res.redirect('/');
    });
});

It looks like express call the get and not the put in my case. Any suggestion?

The browser itself will only do GET and PUT from a <form> . So, your browser is sending a POST and your server doesn't have a handler for that POST.

The ?_method=put that you added to your URL looks like you're hoping to use some sort of method conversion or override tool on the server so that it will recognize that form POST as if it were a PUT. You don't show any server-side code to recognize that override query parameter so apparently your server is just receiving the POST and doesn't have a handler and thus you get the error CANNOT POST /edit/62185a7efd51425bbf43e21a .

There are several different middleware solutions that can perform this override. Here's one from Express: http://expressjs.com/en/resources/middleware/method-override.html and you can see how to deploy/configure it in that document.

Basically, you would install the module with:

npm install method-override

and then add this to your server:

const methodOverride = require('method-override')

// override with POST having ?_method=PUT
app.use(methodOverride('_method'));

This will look at incoming POST requests with the ?_method=PUT query string and will modify the method per the parameter in the query string so that app.put() will then match it.

This is to be used when the client can only do GET or POST and can't do other useful methods such as PUT or DELETE.


As a demonstration, this simple app works and outputs got it! back to the browser and /edit/123456789?_method=put in the server console when I press the Update User button in the HTML form.

const app = require('express')();
const path = require('path');
const methodOverride = require('method-override');


app.use(methodOverride('_method'));

app.get("/", (req, res) => {
    res.sendFile(path.join(__dirname, "temp.html"));
});

app.put('/edit/:id', (req, res) => {
    console.log(req.url);

    res.send("got it!");
});

app.listen(80);

And, temp.html is this:

<!doctype html>
<html lang="en">
<head>
    <meta charset="UTF-8">
</head>
<body>
    <form action="/edit/123456789?_method=put" method="POST">
         <br>
         <input type="text" value="hello" name="name" class="form-control">
         <br>
         <input type="text" value="hello@gmail.com" name="email" class="form-control">
         <br>

         <button type="submit" class="btn btn-info btn-block mt-3">Update User</button>
     </form>
</body>
</html>

You can create chainable route handlers for a route path by using app.route(). Because the path is specified at a single location, creating modular routes is helpful, as is reducing redundancy and typos. Note : you must change the method in side form tag to PUT

<form action="/edit/<%= address.id %>" method="put">
//Backend.js
router.route('/edit/:id')
 .get((req, res) => {
    res.send('Get a random book')
 })
.put((req, res) => {
  res.send('Update the book')
})

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM