简体   繁体   English

为什么 express 调用我的 get 路线而不是我的 put 路线?

[英]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.它工作正常,我可以看到从 mongodb 到 myForm 的数据。 Now after I update some data in this form and click the udpdate button i get : Cannot POST /edit/62185a7efd51425bbf43e21a现在,在我更新此表单中的一些数据并单击 udpdate 按钮后,我得到: 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.在我的情况下,它看起来像是 express 调用 get 而不是 put 。 Any suggestion?有什么建议吗?

The browser itself will only do GET and PUT from a <form> .浏览器本身只会从<form>执行 GET 和 PUT。 So, your browser is sending a POST and your server doesn't have a handler for that POST.因此,您的浏览器正在发送一个 POST,而您的服务器没有该 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.您添加到 URL 的?_method=put看起来您希望在服务器上使用某种方法转换或覆盖工具,以便它能够识别该表单 POST,就好像它是一个 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 .您没有显示任何服务器端代码来识别覆盖查询参数,因此显然您的服务器只是接收 POST 并且没有处理程序,因此您收到错误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.这是 Express 中的一个:http: //expressjs.com/en/resources/middleware/method-override.html ,您可以在该文档中查看如何部署/配置它。

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.这将使用?_method=PUT查询字符串查看传入的 POST 请求,并将根据查询字符串中的参数修改方法,以便app.put()然后匹配它。

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.当客户端只能执行 GET 或 POST 而不能执行其他有用的方法(例如 PUT 或 DELETE)时,将使用此选项。


As a demonstration, this simple app works and outputs got it!作为演示,这个简单的应用程序可以工作并且输出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.当我按下 HTML 表单中的更新用户按钮时,返回浏览器并/edit/123456789?_method=put在服务器控制台中。

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:而且, temp.html是这样的:

<!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().您可以使用 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注意:您必须将表单标签中的方法更改为 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')
})

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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