fetch发送DELETE请求被当作GET处理,Express+Mongoose删除后跳转异常
问题根因
- 你看到的GET 404请求和你写的fetch DELETE请求是两次独立的请求:你的删除按钮是带
href属性的<a>元素,点击时浏览器会默认触发原生GET跳转请求,你的click事件监听没有阻止这个默认行为,所以一次点击同时触发了两次请求:- 你代码里写的fetch DELETE请求,正常匹配到Express的
app.delete路由,成功执行了数据库删除逻辑 - 浏览器自动发起的GET
/article/delete/:id请求,你的Express没有定义对应GET路由,所以返回404,这就是你看到的报错来源
- 你代码里写的fetch DELETE请求,正常匹配到Express的
- 重定向不生效的原因:Express返回的302重定向是响应给fetch异步请求的,fetch默认会自动跟随重定向拉取
/deleted的页面内容,但不会触发浏览器主窗口跳转,所以你看不到页面切换。
解决方案
第一步:修改前端代码,阻止默认行为+手动跳转
在click事件回调第一行添加event.preventDefault()阻止<a>标签的默认跳转,删除成功后手动控制页面跳转:
const deleteBtn = document.querySelector('#DELETE'); deleteBtn.addEventListener('click', (event)=> { // 核心:阻止a标签默认GET跳转行为 event.preventDefault(); const parts = event.target.href.split('/'); const id = parts[parts.length - 1]; fetch('/article/delete/' + id, { method: 'DELETE', headers: { 'Content-Type': 'application/json' } }) .then(response => { if(response.ok) { // 删除成功后手动跳转到删除成功页 window.location.href = '/deleted'; } }) .catch(error => console.log(error)); });
第二步:优化后端路由(可选,更符合规范)
DELETE接口不需要返回重定向,直接返回状态码即可,避免不必要的资源请求:
app.delete('/article/delete/:id', (request, response)=> { Article.deleteOne({ _id: request.params.id}, (error)=> { if(error) { console.log(error); return response.sendStatus(500); } response.sendStatus(200); }); });
内容的提问来源于stack exchange,提问作者Jonathan Kuhl
相关产品推荐
相关产品推荐

