简体   繁体   English

使用节点时,mongoose,并表达为什么我的删除功能可以使用 GET 方法而不是 DELETE 方法?

[英]When using node, mongoose, and express why do my delete functionality work with a GET method but not a DELETE method?

I am working on a crud project and I want to delete a item by id using MongoDB, express, and node.我正在处理一个 crud 项目,我想使用 MongoDB、express 和 node 按 id 删除一个项目。

here is the functionality for me to delete an item:这是我删除项目的功能:

router.get('/delete/:id', async (req, res) => {
    try {
        const topic = await Topic.findById(req.params.id)
        await Topic.remove({ _id: req.params.id })
        res.redirect('/dashboard')
    } catch (error) {
       console.log(error) 
    }    
})

here is the ejs portion for when a user click on the item to be deleted:这是用户单击要删除的项目时的 ejs 部分:

                <div class="modifyTopic">
                    <a href="/edit/<% topic._id %>"><i class="fas fa-edit fa-2x"></i></a>
                    <a href="/delete/<%= topic._id %>"><i class="fas fa-trash fa-2x"></i></a>
                </div>

this code actually works but when I change the get method to a delete method like this:这段代码实际上是有效的,但是当我将 get 方法更改为这样的 delete 方法时:

router.delete('/delete/:id', async (req, res) => {
    try {
        const topic = await Topic.findById(req.params.id)
        await Topic.remove({ _id: req.params.id })
        res.redirect('/dashboard')
    } catch (error) {
       console.log(error) 
    }    
})

it do not work.它不起作用。 I get a message in the browser saying "Cannot GET /delete/62def4aae6c2c1914cfa145fer3" why is this?我在浏览器中收到一条消息“无法获取 /delete/62def4aae6c2c1914cfa145fer3”,这是为什么? I should be using the delete method instead of get right?我应该使用删除方法而不是正确吗? How can I make this work with the delete approach?如何使用删除方法进行这项工作?

Clicking on an <a> tag performs a GET request.单击<a>标记会执行 GET 请求。 In order to hit your router.delete() route, you have two options...为了击中你的router.delete()路由,你有两个选择......

Option #1选项1

Intercept the event with JavaScript and send an async DELETE request.使用 JavaScript 拦截事件并发送异步DELETE请求。

Include a <script> section in your view with something like the following...在您的视图中包含一个<script>部分,如下所示...

// Delegated event listener
document.addEventListener("click", async (e) => {
  const del = e.target.closest("a i.fa-trash");
  
  if (del) { // clicked on a "trash" icon
    e.preventDefault();
    const { href } = del.closest("a"); // get the href
    const res = await fetch(href, {
      method: "DELETE",   // send a DELETE request
      redirect: "manual", // don't follow redirects
    });
    if (res.ok) {
      // request successful
      window.location = res.headers.get("location") ?? "/dashboard";
    } else {
      console.error(res);
    }
  }
});

In this scenario, you may not want to respond with a redirect since you're handling the follow-up action client-side.在这种情况下,您可能不想响应重定向,因为您正在处理客户端的后续操作。 See this answer for more details有关更多详细信息,请参阅此答案

Option #2选项 #2

Use the method-override middleware to simulate a DELETE request.使用方法覆盖中间件来模拟DELETE请求。

Register the middleware in your app在您的应用中注册中间件

const methodOverride = require("method-override");

app.use(methodOverride("_method", {
  methods: ["GET", "POST"], // GET is not recommended, see below
});

and add the appropriate query string parameter to your links并将适当的查询字符串参数添加到您的链接

<a href="/delete/<%= topic._id %>?_method=DELETE">
  <i class="fas fa-trash fa-2x"></i>
</a>

Keep in mind that deleting via GET request can be very dangerous .请记住,通过 GET 请求删除可能非常危险 I would at the very least recommend using a <form> instead我至少会推荐使用<form>代替

<form action="/delete/<%= topic._id %>?_method=DELETE" method="POST">
  <button type="submit" class="btn-text">
    <i class="fas fa-trash fa-2x"></i>
  </button>
</form>

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

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