【问题标题】:How to display nodejs mysql results on html page?如何在html页面上显示nodejs mysql结果?
【发布时间】:2021-08-09 00:52:13
【问题描述】:

我正在学习 Nodejs 作为我熟悉的 PHP 的替代品。通常我会使用 Ajax 调用 PHP 脚本来返回 json 数据并从那里开始工作。在网站上展示它非常简单。

现在我正在尝试使用 Nodejs 在页面加载时从 MySQL 数据库加载数据并将其显示在 html 页面上。以下是我的 app.js 脚本。

我在下面列出了两个想法 #1 使用 socket.io 和 #2 只是加载它,它们不是同时运行的,只是不同的尝试。

const express = require('express');
const mysql = require('mysql');

const app = express();
const http = require('http').Server(app);
const io = require('socket.io')(http);

const port = process.env.PORT || 3000;

app.use(express.static(__dirname + '/public'));

app.get('/', (req, res) => {
    res.sendFile(__dirname + '/index.html');
});

//mysql

var connection = mysql.createConnection({
    host: '...',
    user: '...',
    password: '...',
    database: '...'
});

io.on('connection', (socket) => {
    socket.on('chat message', (msg) => {
        io.emit('chat message', msg);
    });
    socket.on('typing', (data) => {
        socket.broadcast.emit('typing', data);
    });
    socket.on('typing_clear', (data) => {
        socket.broadcast.emit('typing_clear', data);
    });

    // #1 - This is one attempt but crashes the app if loaded from a second page... It works but then if I open a second browser and load the url it crashes the app. I just want this to load once each time a user goes to the URL to load historical data from the database.

    socket.on('get_posts', (data) => {
        connection.connect();

        connection.query('SELECT `status` FROM `training`', function (error, results) {
            if (error) {
                console.log(error);
            }
            var string = JSON.stringify(results);
            // console.log(string);
            io.emit('get_posts', string);

        });

        connection.end();

    });

});


// #2 - This is another attempt. It grabs the data and successfully console log the data. I don't know what do from there. How can I get it to the client side JS page to use json parse and display it.

connection.connect();

connection.query('SELECT `status` FROM `training`', function (error, results) {
    if (error) {
        console.log(error);
    }
    var string = JSON.stringify(results);
    console.log(string);

});

connection.end();


http.listen(port, () => {
    console.log(`Socket.IO server running at http://localhost:${port}/`);
});

我在客户端有第二个 JS 脚本,它使用 socket.io 和其他人做前端工作。

我是不是搞错了?


编辑: 这是客户端JS脚本的相关部分。

load();
function load() {
    socket.emit('get_posts', "none");
}

socket.on('get_posts', function (data) {

    var results = JSON.parse(data);

    jQuery.each(results, function (index, item) {

        var status = item.status;
        var sticky = '<div class="sticky">' + status + '</div>';
        $("#messages").append(sticky);
    });

    var x = '<div class="sticky">END</div>';
    $("#messages").append(x);
});

#2 错误:

我在本地主机上执行此操作以进行测试。我做 nodemon app.js 并转到 localhost:3000。

看起来不错,加载数据并按预期显示。然后我打开第二个浏览器窗口以查看其他人如何查看它。它加载 html 但不加载数据,并且在服务器控制台(VS Code)中我得到:

Socket.IO server running at http://localhost:3000/
events.js:292
      throw er; // Unhandled 'error' event
      ^

Error: Cannot enqueue Handshake after invoking quit.
    at Protocol._validateEnqueue (/Users/username_hidden/node/node_modules/mysql/lib/protocol/Protocol.js:215:16)
    at Protocol._enqueue (/Users/username_hidden/node/node_modules/mysql/lib/protocol/Protocol.js:138:13)
    at Protocol.handshake (/Users/username_hidden/node/node_modules/mysql/lib/protocol/Protocol.js:51:23)
    at Connection.connect (/Users/username_hidden/node/node_modules/mysql/lib/Connection.js:116:18)
    at Socket.<anonymous> (/Users/username_hidden/node/app.js:36:20)
    at Socket.emit (events.js:315:20)
    at Socket.emitUntyped (/Users/username_hidden/node/node_modules/socket.io/dist/typed-events.js:69:22)
    at /Users/username_hidden/node/node_modules/socket.io/dist/socket.js:428:39
    at processTicksAndRejections (internal/process/task_queues.js:75:11)
Emitted 'error' event on Connection instance at:
    at Connection._handleProtocolError (/Users/username_hidden/node/node_modules/mysql/lib/Connection.js:423:8)
    at Protocol.emit (events.js:315:20)
    at Protocol._delegateError (/Users/username_hidden/node/node_modules/mysql/lib/protocol/Protocol.js:398:10)
    at Handshake.<anonymous> (/Users/username_hidden/node/node_modules/mysql/lib/protocol/Protocol.js:232:10)
    at Handshake.emit (events.js:315:20)
    at Handshake.Sequence.end (/Users/username_hidden/node/node_modules/mysql/lib/protocol/sequences/Sequence.js:78:12)
    at /Users/username_hidden/node/node_modules/mysql/lib/protocol/Protocol.js:236:14
    at processTicksAndRejections (internal/process/task_queues.js:75:11) {
  code: 'PROTOCOL_ENQUEUE_AFTER_QUIT',
  fatal: false
}
[nodemon] app crashed - waiting for file changes before starting...

发现另一个帖子指出您不需要 connection.connect();和 connection.end() 如果已经连接。到目前为止似乎已修复它...正在进行测试。

【问题讨论】:

  • 您的 #2 不是一个端点,它只是在您启动服务一次时运行。但你的套接字 io 看起来不错。现在有什么困扰你。
  • @PavanKumarTS,我添加了更多代码和错误代码以及解释。我不确定这意味着什么,我一直在进行故障排除,但我仍在学习。我也不确定 emit 是否有意义,因为其他用户可能已经加载了旧数据并且不需要再次查看它。

标签: mysql node.js socket.io


【解决方案1】:

使用如下所示的 REST api 替换您的第二个代码

const connection = mysql.createConnection({
  host: dbConfig.HOST,
  user: dbConfig.USER,
  password: dbConfig.PASSWORD,
  database: dbConfig.DB
});

// open the MySQL connection
connection.connect(error => {
  if (error) throw error;
  console.log("Successfully connected to the database.");
});
app.get('/get-status', (req, res) => {
     connection.query('SELECT `status` FROM `training`', function (error, results) {
         if (error) {
             console.log(error);
         }
         res.send(results);
     });
  });

现在,您可以在前端使用 ajax 来使用 jquery 获取 REST 数据

jQuery.get( "/get-status", function( data ) {
    jQuery.each(data , function (index, item) {
        var status = item.status;
        var sticky = '<div class="sticky">' + status + '</div>';
        $("#messages").append(sticky);
    });
    var x = '<div class="sticky">END</div>';
    $("#messages").append(x);
});

现在我建议 abave 是针对您的第二种情况的 REST api 解决方案。如果你喜欢一开始就使用套接字,理解起来会有点困难尝试理解 websockets 是如何工作的,那么它会很容易。

【讨论】:

  • 好的,如果我尝试这种方法,它可以在浏览器窗口#1 中工作,但随后我进入浏览器窗口#2,它会崩溃。我得到 events.js:292 throw er; // 未处理的“错误”事件错误:调用退出后无法将握手入队。在 Connection 实例上发出“错误”事件:...加上一堆相同的东西。
  • 这是mysql连接的问题。编辑您的 nodejs 应用程序并在开始时创建连接。请参阅编辑后的答案。像上面一样,不要每次都调用 connect 和 end
  • 好的,这是又向前迈出了一步,但最终我得到了错误:连接丢失:服务器关闭了连接。在连接实例上发出“错误”事件:致命:真,代码:“PROTOCOL_CONNECTION_LOST”。添加 connection.end() 会给出原始错误。
  • 您可以在这里stackoverflow.com/q/14087924/7887883查看相关答案。但我建议bezkoder.com/node-js-rest-api-express-mysql 更好的例子
  • 你看到的问题是mysql连接会随着时间的推移而丢失,或者如果手动关闭/断开连接。所以最好使用连接处理程序或连接池的概念,以便在必要时提供连接
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-03-10
  • 1970-01-01
  • 2013-12-15
  • 2019-10-23
  • 2012-11-20
相关资源
最近更新 更多