Ajax POST запрос запускается дважды для Sequelize.Create в Node.js / Express - PullRequest
0 голосов
/ 22 октября 2019

Нет, 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 абсолютно ограничило число вставляемых пользователей до одного).

Для безопасности вот модальная папка:

  • INDEX.JS
"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;

  • USERS.JS
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. Код внутри каждого из этих «файлов» полностью совпадает.

1 Ответ

0 голосов
/ 23 октября 2019

Я упоминал в первом предложении этого поста, что я уже использовал e.preventDefault() и e.stopImmediatePropagation() и e.stopPropagation().

Только что я вернулся к коду и заново ввел e.stopImmediatePropagation(), и теперь он работает. Потому что программирование.

Единственное, что я могу сказать, это то, что теперь я указываю event в параметрах функции onclick. Если вы столкнулись с той же проблемой и поставили все три event примера, попробуйте избавиться от e.stopPropagation() и оставить два других.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...