一、问题描述
进入后台仪表盘页面后,文章总数、专栏数量、留言总数等统计卡片显示为空白或始终为 0,而非真实数据。
二、排查思路
①查看提交状态
前端在点击“直接发布”后弹出“保存成功”,但文章实际是草稿状态。这说明前端提交成功,后端也保存了,但状态字段未被正确设置为 published。
②检查后端状态设置逻辑
打开 internal/handler/admin/post.go,找到 Save 方法。
看到状态由 action := c.PostForm(action;) 决定,action == publish; 时才会设为 published,否则默认 draft。 如果后端从表单中读取到的 action 值为空字符串,文章就会变成草稿状态。
因此下一步需要确认:后端究竟收到了什么 action 值?
③通过浏览器 Network 面板查看实际请求
打开开发者工具 → Network 标签,点击“直接发布”按钮。
找到 /posts/save 的 POST 请求,查看 Form Data 或 Payload。
发现请求体中包含 title、content、column_id 等字段,但完全没有 action 字段,或者其值为空。这说明前端根本没有把 action 参数发送给后端。
④回溯前端提交逻辑
JavaScript 提交
function submitPost() {
const form = document.getElementById('postForm');
const formData = new FormData(form); // 直接收集表单数据
fetch(adminPath + '/posts/save', {
method: 'POST',
body: formData
});
}
核心原因:
FormData 构造函数在收集表单数据时,会遍历表单中所有带 name 属性的可输入元素(select),但会忽略 button 元素,除非该按钮作为表单提交的触发者被浏览器识别。
在异步 fetch 提交的场景下,表单并未通过浏览器的默认行为提交,而是由 JavaScript 主动调用了 fetch。此时 FormData 无法感知是哪个按钮触发了本次操作,因此按钮上的 name="action" 和 value=publish 或 value=draft 完全不会被添加到 FormData 中,导致后端无法获取 action 值。
三、修复方案
①将按钮类型改为普通按钮
<button type="button" onclick="submitPost('publish')" class="btn btn-primary">直接发布</button>
<button type="button" onclick="submitPost('draft')" class="btn btn-success">保存草稿</button>
不再依赖按钮的 name 和 value 属性,而是通过函数参数直接传递操作类型。
②在提交函数中手动添加 action
function submitPost(action) {
const form = document.getElementById('postForm');
document.getElementById('content').value = vd.getValue();
const formData = new FormData(form);
formData.append('action', action); // 显式追加 action 字段
// ... fetch 请求
}
暂无评论,快来抢沙发吧!