我不知道如何发出 AJAX 请求

I can't figure out how to make an AJAX request

提问人:Andrey 提问时间:8/14/2023 最后编辑:Andrey 更新时间:8/14/2023 访问量:80

问:

我希望当单击“发送到数据库”按钮时,表单中的数据将发送到数据库并在表单中输出。现有表的新行。

我有一个表,下面是一个按钮,它反过来调用一个表单来将数据发送到数据库(至少这是它的本意)

<!--Actually the button calling the form and the table-->
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Mine_contract</title>
    <link href="new.css" rel="stylesheet"/>
    <script src="script.js" defer></script>
</head>
<body>
    <table id="mine_info">
        <tr>
            <th>№</th>
            <th>Number</th>
            <th>Name</th>
            <th>Address</th>
            <th>Full name of the director</th>
            <th>Phone number</th>
        </tr>
        <tr>
            <td><p>1</p></td>
            <td><p>1</p></td>
            <td><p>Example name</p></td>
            <td><p>Example address</p></td>
            <td><p>Full name director</p></td>
            <td><p>+00000000000</p></td>
        </tr>
    </table>
    <div class="popup">
        <div class="popup__container">
            <div class="popup__wrapper">
                <div id="wrapper">
                    <form action="(I don't understand if there should be something here)" method="POST" class="form">
                    <button class="exit" class="exit" id="closeButton" onclick="delRow()">х</button>
                    <div class="string">
                        <label for="id">№:</label>
                        <input type="number" id="id" name="id" required>
                    </div>
                    <div class="string">
                        <label for="N_m">Number:</label>
                        <input type="text" id="N_m" name="n_m" required>
                    </div>
                    <div class="string">
                        <label for="name">Name:</label>
                        <input type="text" id="name" name="name_m"  required>
                    </div>
                    <div class="string">
                        <label for="Adr">Address:</label>
                        <input type="text" id="Adr" name="Adr_m" >
                    </div>
                    <div class="string">
                        <label for="Full_name">Full name of the director:</label>
                        <input type="text" id="Full_name" name="director" required>
                    </div>
                    <div class="string">
                        <label for="Phone">Phone number:</label>
                        <input type="tel" id="Phone" name="Phone_number" placeholder="Например +00000000000" required>
                    </div>
                        <button type="submit" name = "submit" id="contact">Send to DB</button>
                    </form>
                </div>
            </div> 
        </div>
    </div>       
    <button id="button" class="button" onclick="addRow()">Open the form</button>
</body>
</html>

我使用脚本调用表单

//script.js
const button = document.querySelector('#button');
const closeButton = document.querySelector('#closeButton');
const form = document.querySelector('.form');
const popup = document.querySelector('.popup');

button.addEventListener('click', () => {
  form.classList.add('open');
  popup.classList.add('popup_open');
});

closeButton.addEventListener('click', () => {
  form.classList.remove('open');
  popup.classList.remove('popup_open');
});

我还在 Node.js 上写了一个后端(如果你可以这么称呼它的话)。

const Pool = require('pg').Pool
const pool = new Pool({
  user: '',
  host: '',
  database: '',
  password: '',
  port: 5432,
})

const getMineinfo = (request, response) => {
    pool.query('SELECT * FROM mine_info', (error, results) => {
       if (error) {
         throw error
    }
    response.status(200).json(results.rows)
     })
}

const createRow = (request, response) => {
    const { n_mine, name_mine, adress, full_name_of_direcor, phone_number } = request.body
  
    pool.query('INSERT INTO mine_info (n_mine, name_mine, adress, full_name_of_direcor, phone_number) VALUES ($1, $2, $3, $4, $5) RETURNING *', [n_mine, name_mine, adress, full_name_of_direcor, phone_number], (error, results) => {
      if (error) {
        throw error
      }
      response.status(201).send(`User added with ID: ${results.rows[0].id}`)
    })
  }

module.exports = {
    getMineinfo,
    createRow,
}//Variables from another file
//another file in which, there are these variables
const express = require('express')
const bodyParser = require('body-parser')
const db = require('./queries')
const app = express()
const port = 3000

app.use(bodyParser.json())
app.use(
 bodyParser.urlencoded({
    extended: true,
  })
)

app.get('/', (request, response) => {
    response.json({ info: 'Node.js, Express, and Postgres API' })
})

app.get('/mine_info', db.getMineinfo)
app.post('/mine_info', db.createRow)

app.listen(port, () => {
    console.log(`App running on port ${port}.`
)})//it works I get the data in the form of JSON by reference http://my-data:3000/mine_info/

正如我所理解并试图弄清楚的那样,对于我想要的东西,我需要提出 AJAX 请求。 但我不明白该怎么做(也许我很愚蠢),但我请你明白这是我第一次尝试制作这样的 Web 应用程序。

我试图弄清楚AJAX文档。我试图通过fetch解决我的问题,但是我遇到了如何克服CORS的问题。我也试图通过XMLHttpRequest解决我的问题,但我没有弄清楚,在我看来,这似乎是一个过时的解决方案(也许不是)。我请求你帮助我,也许并非一切都像我想象的那样困难,我非常感谢那些读过这个长问题的人。

JavaScript HTML 节点 .js ajax

评论

1赞 Jaromanda X 8/14/2023
fetch 和 XMLHttpRequest 是唯一可供您使用的 AJAX 工具(您的代码也不使用)......可以使用模块在服务器端修复 CORS 问题cors
0赞 Andrey 8/14/2023
@JaromandaX,是的,我知道fetch和XMLHttpRequest是解决这个问题的唯一工具,不幸的是我不知道如何使用它们。至于服务器端的 CORS 模块,感谢您的提示,最有可能的是,规定标头将帮助我避免 CORS 问题。但是我对 AJAX 有严重的问题,我什至不明白请求应该位于何处(headers("Access-Control-Allow-Origin: *"); header("Content-Type: application/json; charset=UTF-8")
0赞 Jaromanda X 8/14/2023
哦,你说你试图使用 fetch 和 XMLHttpRequest - 对不起,误解了你说的话
0赞 Andrey 8/14/2023
@JaromandaX,不要道歉,我知道我的问题很长,可以不替换它。在我缺乏理解的情况下,只有我应该受到责备。

答:

1赞 traynor 8/14/2023 #1

您需要从输入字段中收集数据,并向此路由发出 POST 请求并传递该数据:

app.post('/mine_info'

因此,您需要:

  1. 将提交事件侦听器添加到窗体

您不需要表单属性,因为您使用 JavaScript 手动发出请求,但添加 CSS 标识符以获取表单元素)

<form id="myForm" class="form">

获取表格:

const form = document.getElementById('myForm');

添加提交事件侦听器:

form.addEventListener('submit', async (e) => {

e.preventDefault();
  1. 收集表单输入字段,并序列化请求有效负载

现在,您需要获取每个输入字段的值。

您可以使用 DOM 选择器选择每个元素,但有一个单行代码可以自动为您执行此操作,使用表单数据(有关详细信息,如果您还需要发送文件,请参阅本指南: 使用 FormData 对象

将表单元素传递给表单数据构造函数

new FormData(form)

现在,您将发出一个 JSON 请求,因此将所有条目转换为将要发布的 JSON 对象。 在服务器上,将处理该 JSON 请求(如果要添加文件,则需要发布多部分请求,并且需要多部分处理中间件,例如 multer)bodyParser

const data = Object.fromEntries(new FormData(form).entries());
  1. 将字段发布到路径

使用 native 来制作 JSON 请求,因此将 JSON 添加为内容类型,并将 JSON 对象编码为参数(有关详细信息,请参阅本指南:使用 Fetch APIfetchbody)

try {
    const response = await fetch('/mine_info', {
        method: 'POST',
        headers: {
            'Content-Type': 'application/json',
        },
        body: JSON.stringify(data),
    });

    // parse response: .text() is for text format, use .json() for JSON response
    const result = await response.text();

    console.log('result', result)

    // show the message in the DOM
    // ..

} catch (error) {
    // show some error message in the DOM
    console.log('err: ', error);
}

(注意:您的服务器使用 发送响应,这意味着它是一种文本格式,因此您需要使用 ,但如果您改用,则需要使用 来解析响应)res.send.text()res.json.json()

完整代码:

const form = document.getElementById('myForm');

form.addEventListener('submit', async(e) => {

    e.preventDefault();

    const data = Object.fromEntries(new FormData(form).entries());
    
    console.log('data to post: ', data);

    try {
        const response = await fetch('/mine_info', {
            method: 'POST',
            headers: {
                'Content-Type': 'application/json',
            },
            body: JSON.stringify(data),
        });

        const result = await response.text();
        console.log('result', result)

        // show the message in the DOM
        // ..
   
    } catch (error) {
        
        // show some error message in the DOM
        console.log('err: ', error);
    }

});
 <form id="myForm">
                    <button class="exit" class="exit" id="closeButton" onclick="delRow()">х</button>
                    <div class="string">
                        <label for="id">№:</label>
                        <input type="number" id="id" name="id" required>
                    </div>
                    <div class="string">
                        <label for="N_m">Number:</label>
                        <input type="text" id="N_m" name="n_m" required>
                    </div>
                    <div class="string">
                        <label for="name">Name:</label>
                        <input type="text" id="name" name="name_m"  required>
                    </div>
                    <div class="string">
                        <label for="Adr">Address:</label>
                        <input type="text" id="Adr" name="Adr_m" >
                    </div>
                    <div class="string">
                        <label for="Full_name">Full name of the director:</label>
                        <input type="text" id="Full_name" name="director" required>
                    </div>
                    <div class="string">
                        <label for="Phone">Phone number:</label>
                        <input type="tel" id="Phone" name="Phone_number" placeholder="Например +00000000000" required>
                    </div>
                        <button type="submit" name = "submit" id="contact">Send to DB</button>
                    </form>

评论

0赞 Andrey 8/14/2023
这对我来说解释了很多,你是一个很酷的人。只是我不在这里,我不明白在前端或后面写这个脚本在哪里(多么可耻()
0赞 traynor 8/14/2023
在前端,将其添加到文件中。与代码的每个元素和部分一起使用,以帮助您更好地理解它script.jsconsole.log
0赞 Andrey 8/14/2023
你是最好的人,你向我解释了一堆我读到的信息,我无法在脑海中构建。
0赞 traynor 8/14/2023
伟大。如果这个答案解决了你的问题,你可以接受它
0赞 Andrey 8/14/2023
好吧,我有点弄清楚了录音,它似乎可以工作(我需要更多的编辑)。为了输出为新行,您只需要 GET 发出类似的请求,我理解正确。