How to handle an incorrect POST request using Node.js?

时间秒杀一切 提交于 2020-08-05 15:26:22

问题


TL;DR
Form submits a POST request with "data/fileUpload".
Server responds 200 and renders a new page. Goody.

Try to upload a new file in the rendered page again.
POST request is now "data/fileUpload/fileUpload".
Server doesn't know what to do. Baddy.

I am not exactly sure what is going on, that's why the title is very vague. I am implementing a simple feature to a Node (Express) application. Here is what this feature does:

  • User uploads a file.
  • User submits the file for review.
  • User receives a response.

Problem

Uploading a file and returning a result functionality works smoothly. After file is uploaded and the server renders a new page, browser is still at "data/fileUpload" url. Trying to upload a second file directs a POST request to the following url "data/fileUpload/fileUpload" which can not be routed by the server.

<!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>

As you can see the form action is "data/fileUpload". This post request is handled by the following router and controllers.

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

The following Router is in data.js. processController is imported from processData.js controller.

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

And this is the Controller for fileUpload and 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" });
    });
};

The following is the incomplete directory tree.
├── app.js
├── controllers
│ └── processController.js
├── package.json
├── routes
│ ├── data.js
├── uploads
│ └── Uploaded.file
└── views
    ├── index.ejs


How can I enable server to go back to the initial page but also send results?


回答1:


You should use res.redirect() combined with req.flash() - connect flash (that at some point got excluded from expressjs bundle) for what you are trying to do. (Which is sending an ok/not-ok message back to front).

res.render() Sends back an html (or any other engine) template back to front and renders - It does not care for what happens next and this can cause problems such as yours (sending a full page as template and messing up data).

res.redirect() redirects the user to another route (by this restarting the request like: GET /some_new_or_even_the_same_route.

req.flash() Can handle returned messages.

Also, with redirect() you could send a status code as the first argument which can act as your processed true/false

I think res.render() is just not the right function to use in your scenario.



来源:https://stackoverflow.com/questions/62750163/how-to-handle-an-incorrect-post-request-using-node-js

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!