新的FormData(this);不工作 // 这是目标所需形式时的回调函数内部

问题描述 投票:0回答:1

ejs 文件,用于将表单数据从 todo.ejs 文件传递到名为 index.js 的 Express 服务器文件。我想要的是,提交后它不应该去任何地方停留在同一页面上并重新加载以反映表单中修改的数据。

为此,我在客户端放置了一些代码来使用 new FormData(this) 手动发送数据,删除表单的默认行为并在之后重新加载以反映效果。

但是不起作用

这里是 script.js,它是包含在 todo.ejs 文件中的静态文件。

document.getElementById("task_form").addEventListener('submit', function(event) {
    event.preventDefault();
    const formData = new FormData(this);
    // for debugging
    // this is printing the data, but not passing to the server.
    var data = {};
    for (let pair of formData.entries()) {
        data[pair[0]] = pair[1];
        console.log(pair[0] + ': ' + pair[1]);
    }
    console.log(data);
    // dubugging ends.

    // Perform the form submission using AJAX/fetch
    fetch('/task', {
        method: 'POST',
        body: formData // Assuming you want to submit form data
    })
    .then(response => {
        if (!response.ok) {
        throw new Error(`HTTP error! Status: ${response.status}`);
        }

        // Handle the redirect by reloading the page
        // window.location.reload(true);
    })
    .catch(error => {
        console.error('Error:', error);
        // Handle errors
    });
});

这是 todo.ejs 文件形式

<!-- enctype="multipart/form-data" content  -->
<form id="task_form" action="/task" method="post">
    <fieldset>
        <legend>Description</legend>
        <input id="task_desc" type="text" name="task" placeholder="define task" value="title">
    </fieldset>
    <fieldset>
        <legend>Duration</legend>
        <label for="start_date">Start : </label>
        <input id="start_date" type="datetime-local" name="start_date"><br>
        <label for="end_date">End : </label>
        <input id="end_date" type="datetime-local" name="end_date"><br>
    </fieldset>
        <input type="submit" value="Add task">
</form>

这是服务器端处理数据的路线。

app.post("/task", (req, res)=>{
  var data = req.body;// this is empty
  console.log(data);// 
  // for debugging
  data.start_date = "2023-11-03T13:44";
  data.end_date = "2023-11-24T13:44";
  var d1 = data["start_date"];
  var d2 = data["end_date"];
  console.log(data);
  if(d1 >= d2) {
    console.log("error d1 >= d2");
    // alert("Add correct date");
  } else{
    data.status = "pending";
    todo.push(data);
    console.log("Correct d1 < d2");
  }

  res.redirect("/todo");
});

我尝试使用

将数据作为js对象传递
document.getElementById('task_form').addEventListener('submit', function(event) {
    event.preventDefault();

    const formData = new FormData(this);
    for (let pair of formData.entries()) {
        console.log(pair[0] + ': ' + pair[1]);
    }
});

它将数据打印到控制台,但不将数据传递到服务器。

请帮忙,我将不胜感激,谢谢!

javascript express ejs form-data
1个回答
0
投票

以下示例执行内容类型为

multipart/form-data
的 POST 请求。使用 addEventListener() 方法时,您可以使用
e.target
获取 FormData 对象的表单元素。当您使用
this
属性调用回调函数时,会使用
onsubmit

就像评论的那样,您可能需要像 multiparty 或 multer 这样的模块来处理请求数据(内容类型

multipart/form-data
)。请参阅,在请求 Nodejs 中获取多部分/表单数据

(在示例中我将 URL 替换为数据 URI 进行测试)

//const url = '/task';
const url = 'data:application/json,{\"status\":\"ok\"}';

document.forms.task_form.addEventListener('submit', e => {
  e.preventDefault();
  const formData = new FormData(e.target);
  // for debugging
  console.log([...formData].join(';'));
  // dubugging ends.

  // Perform the form submission using AJAX/fetch
  fetch(url, {
      method: 'POST',
      body: formData // Assuming you want to submit form data
    })
    .then(response => {
      if (!response.ok) {
        throw new Error(`HTTP error! Status: ${response.status}`);
      }
    })
    .catch(error => {
      console.error('Error:', error);
      // Handle errors
    });
});
fieldset {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
}
<form name="task_form" action="/task" method="post">
  <fieldset>
    <legend>Description</legend>
    <input type="text" name="task" placeholder="define task" value="title">
  </fieldset>
  <fieldset>
    <legend>Duration</legend>
    <label>Start: <input type="datetime-local" name="startdate"></label>
    <label>End: <input id="end_date" type="datetime-local" name="end_date"></label>
  </fieldset>
  <input type="submit" value="Add task">
</form>

© www.soinside.com 2019 - 2024. All rights reserved.