Нет, 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));
})
}
Очень простые вещи. И все же, из-за того, что я ничего не делаю (кроме взлома маршрута API с помощью итерационной переменной и оператора if, краткосрочного решения), маршрут запускается только один раз.
Имейте в виду, я возвращаюсь кобласть, в которой я не особенно знакома: Sequelize. Существует вероятность того, что из-за некоторой проблемы с секвелированием команда будет запускаться дважды, а не один раз (хотя, как я уже упоминал, добавление хака в маршрут API абсолютно ограничило число вставляемых пользователей до одного).
Для безопасности вот модальная папка:
"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 может поставить меня под угрозу, я совершенно уверен, что это почти совершенно не связано с продолжением, и это больше проблема с маршрутом, сервером и / или вызовом ajax.
Пожалуйста, дайте мне знать, если у вас есть какие-либо ответы. Я в течение часа копался в Google и нашел либо смехотворно старые ответы, либо те, которые просто не работают. Удачи!
ОБНОВЛЕНИЕ
[Снимок экрана вкладки сети] [1]
Это часто встречающаяся проблема, как ни страннодостаточно: ajax-вызов объективно работает (маршрут API «регистрации» отправляет нужную информацию непосредственно в базу данных), и все же, через несколько секунд или минут после успешного пост-запроса, консоль Chrome будет активирована:
POST http://localhost:3000/api/signup net::ERR_EMPTY_RESPONSE
Эта проблема была решена, все еще видя повторяющиеся вызовы ajax
Вот еще один снимок экрана с чуть более подробной информацией ввкладка Сеть: [Более подробная информация о сети] [2]
ОБНОВЛЕНИЕ 2
Я обнаружил, что что-то под названием VM1421
работает рядом с моим logic.js
файл. Результаты поиска в Google не отображаются (или что-то подобное). Кроме того, вкладка «Сеть» имеет одно важное различие между двумя вызовами API: один из них «инициируется» с помощью logicjs
, другой - с помощью VM1421 logic.js
. Код внутри каждого из этих «файлов» полностью совпадает.