不,e.stopPropagation()
和 e.preventDefault()
不起作用。是的,我 100% 肯定我没有点击“提交”按钮两次。不,我不会使用 unbind
,因为现在是 2019 年。
现在我们已经解决了这个问题:
我有一个非常简单的登录/注册表,当点击提交按钮时,它会运行两次 api POST 路由。这是表单的前端代码:
$(document).ready(function(){
let timesTriggered = 0;
$("#signup").on("click", function() {
timesTriggered++;
event.preventDefault();
event.stopPropagation();
console.log(timesTriggered);
let newUser = {
username: $("#username").val(),
password: $("#password").val()
};
$.post("/api/signup", newUser);
});
});
这是表格本身:
<div id = "user-password-field">
<input id = "username" name = "username" type="text" placeholder = "Username">
<input id = "password" name = "password" type="password" placeholder = "Password">
<button id = "login">Login</button>
<button id="signup">Sign Up</button>
</div>
这是api路线:
let User = require("../models/Users");
module.exports = function(app) {
let db = require("../models");
app.post("/api/signup", function(req, res) {
console.log(req.body);
db.User.create({
username: req.body.username,
password: req.body.password
}).catch(err => console.log(err));
})
}
很简单的东西。然而,我没有做任何事情(除了使用迭代变量和 if 语句破解 api 路由,一个短期解决方案)使路由只运行一次。
请记住,我正在重新审视一个我并不特别熟悉的领域: Sequelize 。有可能某些 sequelize 问题导致命令运行两次而不是一次(尽管,正如我之前提到的,向 api 路由添加 hack 绝对确实将插入的用户数量限制为一个)。
为了安全起见,这是模态文件夹:
"use strict";
var fs = require("fs");
var path = require("path");
var Sequelize = require("sequelize");
var basename = path.basename(module.filename);
var env = process.env.NODE_ENV || "development";
var config = require(__dirname + "/../config/config.json")[env];
var db = {};
if (config.use_env_variable) {
var sequelize = new Sequelize(process.env[config.use_env_variable]);
} else {
var sequelize = new Sequelize(config.database, config.username, config.password, config);
}
fs
.readdirSync(__dirname)
.filter(function(file) {
return (file.indexOf(".") !== 0) && (file !== basename) && (file.slice(-3) === ".js");
})
.forEach(function(file) {
var model = sequelize["import"](path.join(__dirname, file));
db[model.name] = model;
});
Object.keys(db).forEach(function(modelName) {
if (db[modelName].associate) {
db[modelName].associate(db);
}
});
db.sequelize = sequelize;
db.Sequelize = Sequelize;
module.exports = db;
module.exports = function(sequelize, DataTypes) {
let User = sequelize.define("User", {
username: DataTypes.STRING,
password: DataTypes.STRING
});
return User;
};
这是
config.json
:{
"development": {
"username": "root",
"password": none of your business,
"database": "yar",
"host": "127.0.0.1",
"port": 3306,
"dialect": "mysql"
},
"test": {
"username": "root",
"password": none of your business,
"database": "yar",
"host": "127.0.0.1",
"dialect": "mysql"
},
"production": {
"username": "root",
"password": null,
"database": "database_production",
"host": "127.0.0.1",
"dialect": "mysql"
}
}
而且,为了更好的衡量,我的
server.js
:const express = require("express");
const session = require("express-session");
const PORT = process.env.PORT || 3000;
const app = express();
let db = require("./models");
app.use(express.static("public"));
app.use(express.urlencoded({extended:true}));
app.use(express.json());
const exphbs = require("express-handlebars");
app.engine("handlebars", exphbs({defaultLayout: "main"}));
app.set("view engine", "handlebars");
// Routes
require("./routes/apiRoutes")(app);
require("./routes/htmlRoutes")(app);
db.sequelize.sync().then(function() {
app.listen(PORT, () => {
console.log("Listening in on " + PORT);
});
});
当我查看 Google Chrome 检查工具中的网络选项卡时,它说 api 路由“/signup”运行了两次。因此,虽然我可以想象对 Sequelize 缺乏充分了解可能会危及我,但我相当肯定这与 sequelize 几乎完全无关,而更多是路由、服务器和/或 ajax 调用的问题。
如果您有任何答案,请告诉我。我已经研究了一个小时的谷歌,发现要么是荒谬的旧回应,要么是根本不起作用的回应。祝你好运!
U P D A T E
[网络选项卡截图][1]
这是一个经常发生的问题,有趣的是:ajax 调用客观有效(“注册”api 路由将正确的信息直接发送到数据库),但是,在 成功发出 发布请求后几秒或几分钟,Chrome 的控制台会拉起来:
POST http://localhost:3000/api/signup net::ERR_EMPTY_RESPONSE
这个问题已经解决了,仍然看到重复的ajax调用
这是另一个屏幕截图,在“网络”选项卡中包含更多信息:
[更具体的网络信息][2]
上传数据 2
我发现
VM1421
与我的 logic.js
文件一起运行。搜索它(或任何类似的东西)时,谷歌上没有显示任何结果。此外,Network 选项卡在两个 api 调用之间确实有一个重要区别:其中一个由 logicjs
“启动”,另一个由 VM1421 logic.js
启动。这些"file"中的每一个中的代码都是完全一致的。
最佳答案
我在这篇文章的第一句话中提到我已经使用了 e.preventDefault()
和 e.stopImmediatePropagation()
和 e.stopPropagation()
。
刚才,我已经回到代码中并重新引入了 e.stopImmediatePropagation()
,现在它可以工作了。因为编程。
我能说的唯一区别是我现在在 onclick 函数参数中指定了 event
。如果您遇到了同样的问题并且已经将所有三个 event
示例都放在了一起,那么请尝试去掉 e.stopPropagation()
并保留其他两个。
关于javascript - 在 Node.js/Express 中为 Sequelize.Create 触发两次 Ajax POST 请求,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58494892/