【问题标题】:Send error message and re-direct in Express.js在 Express.js 中发送错误消息和重定向
【发布时间】:2021-05-08 02:32:34
【问题描述】:

学习 Express.js。我有以下简单的 HTML 表单:

<!DOCTYPE html>
<html lang="en" dir="ltr">
  <head>
    <meta charset="utf-8">
    <title>Calculator</title>
  </head>
  <body>
    <h1>Calculator</h1>
    <form action="/" method="post">
      <input type="text" name="num1" placeholder = "First Number" value=""> <br>
      <input type="text" name="num2" placeholder = "Second Number" value=""> <br>
      <button type="submit" name="submit">Calculate</button>
    </form>
  </body>
</html>

用户应该输入两个数字,然后返回它们的总和。简单的 Express 服务器在这里。 body-parser 被 Express app 包含在 node_modulesused 中,以便操作 req 对象并提取表单数据。

const express = require("express");
const bodyParser = require("body-parser");
const app = express();

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

app.listen(3000, () => {
  console.log("Server spun on port 3000.")
});

app.get("/", (req, res) => {
  console.log("Serving a GET request at root route.");
  res.sendFile(absoluteDirPath() + "index.html");
});

app.post("/", (req, res) => {
  console.log("Serving a POST request at root route.");
  let num1 = Number(req.body.num1);
  let num2 = Number(req.body.num2);
  if(isNaN(num1) || isNaN(num2)) {
     res.send("<p>Need numerical values.</p>"); 
   } else {
    res.send("<h3>Result: " + (num1 + num2) + "</h3>");
  }
  // How can I re-direct the user here? 
});

function absoluteDirPath() {
  const path = require('path');
  return __dirname + path.sep;
}

我有兴趣将用户重定向到POST 中间件中的index.html,这样他们就可以在不刷新 URL 的情况下再次使用计算器,无论他们是否成功使用它。由于这是在后端,我无权访问 window 对象,我无法直接使用它。不确定如何做到这一点。有什么想法吗?

【问题讨论】:

  • 你必须做出决定。您想继续使用服务器进行所有操作,还是想使用 AJAX 调用 API 来处理您的帖子/响应。否则,您所做的事情会使 Post/Redirect/Get 设计模式无效,该模式允许重新加载、共享或添加表单提交后显示的页面而不会产生不良影响,例如再次提交表单。

标签: javascript node.js express post redirect


【解决方案1】:

快速重定向:

res.redirect('/');

这并不完全类似于 window.location,但它确实重定向。

但是,我不明白您为什么应该重定向,因为您正在向客户端发送消息,并且在他们看到之前您已经重定向了他们。

解决问题的更好方法是使用 AJAX(提交表单而不重新加载页面);查看这个 jQuery 示例(显然是客户端):

function submitFormWithoutReloading() {
   $.ajax({
      type: "POST",
      url: "/",
      data: {
         num1: $('#idOfYourFirstInput').val(),
         num2: $('#idOfYourSecondInput').val()
      },
      success: function(res) {
         alert(res); // This is what the server returns
      }
   });
}

另外,您可以只使用提供的变量__dirname 作为绝对路径。

【讨论】:

  • 为了清楚起见,我没有投反对票。验证确实听起来像是客户应该做的事情。感谢您的信息!那么,这个函数是否应该在我的 HTML &lt;form&gt; 之后的 &lt;script&gt; 标记内?我是否只需将其作为函数写入链接的.js 文件中?您将在哪里编写此函数以确保在用户单击按钮时调用它?按钮的事件处理程序?
  • 因此,如果您使用 AJAX,则无需将信息放入表单中,除非您提供表单和 ID,否则您可以使用 data: $('#idOfMyForm').serialize(),它会给出相同的结果.关于脚本,您可以将其放在脚本标签或另一个.js 文件中。只需使用调用 AJAX 函数 (submitFormWithoutReloading()) 的事件侦听器创建一个按钮(常规按钮)。
  • 知道了,谢谢。我接受了这个答案,但事实是它让我进入了一个更大的兔子洞,最好用另一个 SO 帖子来解释,我发了 here。您能提供的任何帮助将不胜感激;当我使用res.sendFile() 向我的客户端发送 HTML 文件时,我似乎无法呈现客户端 JavaScript / jQuery。这使我的客户端验证变得不可能。
  • 解决方法很简单。您必须告诉 express 哪个目录是“公共的”(可以由客户端查看)。需要路径,然后只需在const app = express() 下添加:app.use(express.static(path.join(__dirname, '/path/to/your/folder/you/want/clients/to/be/able/to/see/the/content)));`
猜你喜欢
  • 2013-11-16
  • 1970-01-01
  • 2022-01-19
  • 1970-01-01
  • 2012-12-30
  • 1970-01-01
  • 2020-04-30
  • 2016-01-02
  • 2018-07-01
相关资源
最近更新 更多