基于Mongoose实现Paste类后点击创建按钮无跳转问题排查求助
问题分析与修复方案
核心问题梳理
你遇到的不跳转问题是多层错误叠加导致的,按优先级排序如下:
- 前后端代码混写错误:你把仅能在Node.js环境运行的
require、mongoose数据库操作、crypto生成密钥等逻辑,直接写到了前端浏览器执行的JS代码里,浏览器没有对应运行环境,代码直接报错中断,自然不会执行跳转。 - 异步逻辑未等待执行:即使忽略前后端分离问题,现有代码里的
generateKey是回调式异步API、Mongoose的create方法也是异步方法,你没有等待异步逻辑执行完就往下走,调用Paste构造函数时id还是null,跳转逻辑自然执行异常。
修复步骤
1. 架构调整:前后端逻辑拆分
正确的执行流应该是:
- 前端点击按钮收集表单数据,通过POST请求发给express后端接口
- 后端负责生成ID、调用Paste类写入MongoDB,返回生成的ID给前端
- 前端拿到返回的ID后再执行页面跳转
2. 后端代码修改
先修改Paste类,适配异步操作:
// Paste.js const db = require("../models/schema"); class Paste { constructor( id, content, title, description, language ) { this.id = id; this.content = content; this.title = title; this.description = description; this.language = language; } // 改为异步方法返回Promise async create() { return await db.create({ id: this.id, content: this.content, title: this.title, description: this.description, language: this.language }) } async find(id) { const r = await db.findOne({ id: id }); if(!r) return false; return { id: r.id, content: r.content, title: r.title, description: r.description, language: r.language } } } module.exports = Paste;
Express新增创建paste的接口:
// 你的express启动文件中新增,确保已经提前连接好mongoose const Paste = require("./classes/Paste"); const { generateKey } = require('crypto'); // 先配置json解析中间件,否则拿不到post的body app.use(express.json()); app.post('/api/create-paste', async (req, res) => { try { const { content, title, description, language } = req.body; // 异步生成ID const id = await new Promise((resolve, reject) => { generateKey("aes", { length: 10 }, (err, key) => { if (err) return reject(err); resolve(key.export().toString("hex")); }) }); const p = new Paste(id, content, title, description, language); await p.create(); res.json({ success: true, id }); } catch (e) { res.status(500).json({ success: false, msg: e.message }); } })
3. 前端代码修改,移除所有Node.js专属逻辑
// 前端页面的JS代码,仅保留DOM操作和请求逻辑 async function registerPaste() { try { let title = document.getElementById("pasteTitle").value; if(title.length > 20) { title = title.slice(0, 40) + `...` } const params = { content: document.getElementById("pasteContent").value, title, description: document.getElementById("pasteDescrp").value, language: document.getElementById("pasteLang").value } // 请求后端接口拿生成的ID const res = await fetch('/api/create-paste', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify(params) }); const data = await res.json(); if(data.success) { window.location.replace(`${window.location.href}/${data.id}`); } else { console.error('创建失败:', data.msg); } } catch (e) { console.error('执行异常:', e); } }
内容的提问来源于stack exchange,提问作者Insane ツ
相关产品推荐
相关产品推荐

