javascript - 在 Node.js/Express 中为 Sequelize.Create 触发两次 Ajax POST 请求

标签 javascript node.js ajax express sequelize.js

不,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 绝对确实将插入的用户数量限制为一个)。

为了安全起见,这是模态文件夹:
  • 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 缺乏充分了解可能会危及我,但我相当肯定这与 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/

    相关文章:

    javascript - 如何使用 Angular.js/Javascript 根据键值对数组进行排序

    javascript - javascript/node.js 中的 JSONP 解析

    javascript - 从 Angular Controller 控制 SoundCloud js sdk

    javascript - 嵌套对象迭代并返回空值键名nodejs

    javascript - Node : Global variables across multiple files

    javascript - 针对 DocumentFragment 的 XPath 查询

    javascript - 从 Node 应用程序将全局对象写入文件

    javascript - 如何访问 JQUERY 中的数组元素?

    javascript - 附加新元素后功能不起作用

    javascript - 通过 AJAX 请求提交时显示未定义值的 Google 电子表格