【问题标题】:How to handle an incorrect POST request using Node.js?如何使用 Node.js 处理不正确的 POST 请求?
【发布时间】:2020-10-26 05:30:39
【问题描述】:

TL;DR
表单提交带有“data/fileUpload”的 POST 请求。
服务器响应 200 并呈现新页面。太好了。

尝试再次在呈现的页面中上传新文件。
POST 请求现在是“data/fileUpload/fileUpload”。
服务器不知道该怎么做。坏蛋。

我不完全确定发生了什么,这就是为什么标题非常模糊的原因。我正在为 Node (Express) 应用程序实现一个简单的功能。 以下是此功能的作用:

  • 用户上传文件。
  • 用户提交文件以供审核。
  • 用户收到回复。

问题

上传文件和返回结果功能运行顺畅。文件上传后服务器渲染一个新页面,浏览器仍然在“data/fileUpload”url。尝试上传第二个文件会将 POST 请求定向到服务器无法路由的以下 url “data/fileUpload/fileUpload”。

<!DOCTYPE html>
    <!-- Boilerplate ... -->
    <body
    <div id="form">
         <%= message %>
         <% if(processed == "true"){ %>
         <%= results %>
         <% }; %>
         <form method='post' action='data/fileUpload' enctype="multipart/form-data">
            <input type='file' name='fileUploaded' id="browseButton" required>
            <input type='submit' value="Upload" id="uploadButton">
      </div>
     <script>
        var uploadField = document.getElementById("browseButton");
        uploadField.onchange = function() {
            if(this.files[0].size > 2097152){
            alert("File is too big!");
            this.value = "";
            };
        };
</script>
</body>
</html>

如您所见,表单操作是“data/fileUpload”。此发布请求由以下路由器和控制器处理。

// Defined in app.js
app.use('/data',  dataRouter); 

以下路由器位于 data.js 中。 processController 是从 processData.js 控制器导入的。

router.post('/fileUpload', [processController.fileUpload, processController.process]);

这是文件上传和处理的控制器。


exports.fileUpload = function(req, res,next) {
   // Upload the file... 
   next(); // calls process function
};

// Process the data. Not implemented
exports.process = function(req, res) {
        res.render('index', {processed:"true", 
            message: "hello", results:"result" });
    });
};

以下是不完整的目录树。
├── app.js
├── 控制器
│ └── processController.js
├── package.json
├── 路线
│ ├── data.js
├── 上传
│ └── Uploaded.file
└── 浏览量
├── index.ejs


如何让服务器返回初始页面同时发送结果?

【问题讨论】:

    标签: node.js express url post routes


    【解决方案1】:

    您应该使用res.redirect() 结合req.flash() - connect flash (that at some point got excluded from expressjs bundle) 来完成您想要做的事情。 (将 ok/not-ok 消息发送回前面)。

    res.render() 将 html(或任何其他引擎)模板发送回前端并呈现 - 它不关心接下来会发生什么,这可能会导致诸如您的问题(将整个页面作为模板发送并弄乱数据)。

    res.redirect() 将用户重定向到另一条路线(通过这种方式重新启动请求,例如:GET /some_new_or_even_the_same_route

    req.flash()可以处理返回的消息。

    另外,使用redirect(),您可以发送一个状态码作为第一个参数,它可以充当您的processed true/false

    我认为 res.render() 只是不适合在您的场景中使用。

    【讨论】:

    • 谢谢!我找到了另一种解决此问题的方法,方法是将表单操作更改为绝对 url:“localhost:3000/data/fileUpload”。显然 localhost 需要在生产中更改一次。
    • @a_a_a 确定!请记住 Absolute URLs contain more information than relative urls, as they also include the protocol (e.g http://) and the domain name. protocol://domain/path - 您的语法假定协议,所以它还不是绝对的。这需要您进一步关注 - 绝对/相对路径各有利弊。 further reading, more reading
    猜你喜欢
    • 2013-03-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-04-03
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多