NodeJS & Express — 从 index.html 运行 index.js 代码

huangapple go评论50阅读模式
英文:

NodeJS & Express -- Run index.js code from index.html

问题

I'm learning NodeJS, Express via Replit.com with a small project. The goal is to create a simple input field that when submitted posts to various channels, such as Discord, Twitter, etc.

The below code runs on replit.com, loads the necessary packages and successfully connects to the Discord Channel.

I can run javascript code in app.js from the html. (Such as send()) Placing such function inside of index.js does not work. How do I access code from index.js (such as the methods from the discord js) to trigger/execute them from the html?

Directory Structure:

index.js
public/
  index.html
  css/
    app.css
  js/
    app.js

index.js:

const express = require("express");
const path = require('path');
const app = express();

app.listen(3000, () => {
  console.log("project is running");
})

app.use(express.static(path.join(__dirname, 'public')));

app.get('/', function(req, res) {
    res.redirect('index.html');
});

const { Client, GatewayIntentBits, Intents } = require('discord.js');
const client = new Client({
  intents: [
    GatewayIntentBits.Guilds,
    GatewayIntentBits.GuildMessages,
  ]
})

client.on("ready", () => {
  console.log("Bot is ready.");
  client.channels.cache.get('1056649564532252XXX').send('yo');
});

client.login(process.env.token);

index.html:

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>Sample Site</title>
  <link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css" integrity="sha384-ggOyR0iXCbMQv3Xipma34MD+dH/1fQ784/j6cY/iJTQUOhcWr7x9JvoRxT2MZw1T" crossorigin="anonymous">
  <style>
    body { padding-top: 50px; }
  </style>
</head>
<body>

  <div class="container">
    <input />
    <button onclick="send()">Send</button>
  </div>

   <script src="js/app.js"></script>

</body>
</html>

app.js:

function send() {
  console.log('sent');
  // this won't work here: client.channels.cache.get('1056649564532252XXX').send('yo');
}
英文:

I'm learning NodeJS, Express via Replit.com with a small project. The goal is to create a simple input field that when submitted posts to various channels, such as Discord, Twitter, etc.

The below code runs on replit.com, loads the necessary packages and successfully connects to the Discord Channel.

I can run javascript code in app.js from the html. (Such as send()) Placing such function inside of index.js does not work. How do I access code from index.js (such as the methods from the discord js) to trigger/execute them from the html?

Directory Structure:

index.js
public/
  indx.html
  css/
    app.css
  js/
    app.js

index.js:

const express = require(&quot;express&quot;);
const path = require(&#39;path&#39;);
const app = express();

app.listen(3000, () =&gt; {
  console.log(&quot;project is running&quot;);
})

app.use(express.static(path.join(__dirname, &#39;public&#39;)));

app.get(&#39;/&#39;, function(req, res) {
    res.redirect(&#39;index.html&#39;);
});

const { Client, GatewayIntentBits, Intents } = require(&#39;discord.js&#39;);
const client = new Client({
  intents: [
    GatewayIntentBits.Guilds,
    GatewayIntentBits.GuildMessages,
  ]
})

client.on(&quot;ready&quot;, () =&gt; {
  console.log(&quot;Bot is ready.&quot;);
  client.channels.cache.get(&#39;1056649564532252XXX&#39;).send(&#39;yo&#39;);
});

client.login(process.env.token);

index.html:

&lt;!DOCTYPE html&gt;
&lt;html lang=&quot;en&quot;&gt;
&lt;head&gt;
  &lt;meta charset=&quot;UTF-8&quot;&gt;
  &lt;title&gt;Sample Site&lt;/title&gt;
  &lt;link rel=&quot;stylesheet&quot; href=&quot;https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css&quot; integrity=&quot;sha384-ggOyR0iXCbMQv3Xipma34MD+dH/1fQ784/j6cY/iJTQUOhcWr7x9JvoRxT2MZw1T&quot; crossorigin=&quot;anonymous&quot;&gt;
  &lt;style&gt;
    body { padding-top: 50px; }
  &lt;/style&gt;
&lt;/head&gt;
&lt;body&gt;

  &lt;div class=&quot;container&quot;&gt;
    &lt;input /&gt;
    &lt;button onclick=&quot;send()&quot;&gt;Send&lt;/button&gt;
  &lt;/div&gt;

   &lt;script src=&quot;js/app.js&quot;&gt;&lt;/script&gt;

&lt;/body&gt;
&lt;/html&gt;

app.js:

function send() {
  console.log(&#39;sent&#39;);
  // this won&#39;t work here: client.channels.cache.get(&#39;1056649564532252XXX&#39;).send(&#39;yo&#39;);
}

答案1

得分: 1

你不能使用 client 变量,因为它是在服务器上定义的,而 send 函数在客户端浏览器上运行。

所以你需要进行一次 ajax 调用返回到服务器并发送输入数据。

服务器将运行消息发送过程。

在 index.js 中,你需要添加新的端点以接受 ajax 请求:

app.post('/send', function(req, res) {
  client.channels.cache.get('1056649564532252XXX').send('yo')

  res.json({ success: true })
});

在 app.js 中:

function send() {
  console.log('sending');

  fetch('/send', { method: 'POST' })
    .then(response => response.json())
    .then(data => console.log('sent', data))
    .catch(error => console.error(error))
}

接受客户端发送的数据

如果你想要接受客户端发送的 body 数据,你需要使用 express.json 中间件。

express.jsonbody-parser.json 相同。

你可以在这里阅读完整文档。

要使用中间件,你需要在需要中间件的路由之前添加一个新的 use

app.use(express.json())

send 路由之前添加这个。

如果客户端发送了格式不正确的 JSON 字符串,这将引发错误。

send 路由中,你需要从客户端获取值。你可以从 req.body 获取它。

要处理这个,你可以阅读这里

在这里,名称是 message

app.post('/send', function(req, res) {
  // 在这里你需要检查消息是否被发送并且它是一个字符串
  if (!req.body.message || typeof req.body.message !== 'string')
    res.status(400).json({ success: false, message: 'No message found' }) // `.status()` 用于设置响应的状态,如果没有设置,默认为 `200`。

  client.channels.cache.get('1056649564532252XXX')
    .send(req.body.message)

  res.json({ success: true })
});

在客户端或 app.js 中:

在使用 fetch 时添加 body

fetch 更改为:

fetch('/send', { method: 'POST', body: JSON.stringify({ message: 'yo this message is from the client' }) })
  .then(response => response.json())
  .then(data => console.log('sent', data))
  .catch(error => console.error(error))

你需要将对象转换为字符串,因为 fetchbody 接受字符串。

参考

英文:

You cannot use client variable because it's defined in the server and send function is running on client browser.

So you need to make an ajax call back to the server and send the input data.

The server will run the message send process.

In index.js you need to add new endpoint to accept the ajax

app.post(&#39;/send&#39;, function(req, res) {
  client.channels.cache.get(&#39;1056649564532252XXX&#39;).send(&#39;yo&#39;)

  res.json({ success: true })
});

In app.js

function send() {
  console.log(&#39;sending&#39;);

  fetch(&#39;/send&#39;, { method: &#39;POST&#39; })
    .then(response =&gt; response.json())
    .then(data =&gt; console.log(&#39;sent&#39;, data))
    .catch(error =&gt; console.error(error))
}

Accepting body from client

If you want to accept body data sent from the client you need to use express.json middleware.

express.json is same as body-parser.json.

You can read the full docs here.

To use a middleware you need to add new use before the routes that need the middleware.

app.use(express.json())

Add this before the send route.

This will throw error if the client send malformed json string.

In the send route you need to get the value from the client. You can get it from req.body.

To handle this you can read here

Here I the name is message

app.post(&#39;/send&#39;, function(req, res) {
  // You need to check here if the message is sent and it&#39;s a string
  if (!req.body.message &amp;&amp; typeof req.body.message === &#39;string&#39;)
    res.status(400).json({ success: false, message: &#39;No message found&#39;}) // `.status()` is used to set the status of the response if not set the default is `200`.

 client.channels.cache.get(&#39;1056649564532252XXX&#39;)
   .send(req.body.message)

  res.json({ success: true })
});

In the client or app.js

Add the body when using the fetch.

Change the fetch to

fetch(&#39;/send&#39;, { method: &#39;POST&#39;, body: JSON.stringify({ message: &#39;yo this message is from the client&#39; }) })
  .then(response =&gt; response.json())
  .then(data =&gt; console.log(&#39;sent&#39;, data))
  .catch(error =&gt; console.error(error))

You need to stringify the object because the fetch body accept string

References

答案2

得分: 0

我的猜测是由于你的app.js中的重定向和服务器函数的调用顺序问题。

当你运行这个应用程序时,首先确保通过node app.js调用,以确保你正在通过服务器提供应用程序。

然后,你需要更新你的app.js中的express部分,使其类似于下面的代码:

const express = require("express");
const path = require('path');
const app = express();

app.use(express.static(path.join(__dirname, 'public')));

app.get('/', function(req, res) {
    res.sendFile(path.join(__dirname, "./public/index.html"));
});

app.listen(3000, () => {
      console.log("项目正在运行");
})

我个人没有使用过discord客户端,但如果你希望它在页面加载之前加载,也可以考虑将其放在app.listen方法之前。

英文:

My guess is that it's due to the redirect in your app.js and the call order of your server function.

First thing when you're running this app, ensure that you're calling via via node app.js to ensure you're serving the application via the server.

Then you'll want to update the express portion of your app.js to resemble the code below:

const express = require(&quot;express&quot;);
const path = require(&#39;path&#39;);
const app = express();

app.use(express.static(path.join(__dirname, &#39;public&#39;)));

app.get(&#39;/&#39;, function(req, res) {
    res.sendFile(path.join(__dirname, &quot;./public/index.html&quot;));
});

app.listen(3000, () =&gt; {
      console.log(&quot;project is running&quot;);
    })

I haven't personally worked with the discord client, but if you'd like it to load before the page it may also be worth putting that above the app.listen method.

huangapple
  • 本文由 发表于 2023年7月12日 23:01:04
  • 转载请务必保留本文链接:https://go.coder-hub.com/76671980.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定