Express return post info to be processed by anothe

2019-07-29 13:29发布

问题:

I have this code:

 app.post('/pst', function(req, res) {
            var data = req.body.convo;

            res.render('waiting.ejs');  //ADDED THIS

            myFunc(data).then(result => {


            res.render('success.ejs');  //THEN THIS

            //---------------------------------
            //clever way to send text file to client from the memory of the server
            var fileContents = Buffer.from(result, 'ascii');
            var readStream = new stream.PassThrough();
            readStream.end(fileContents);
            res.set('Content-disposition', 'attachment; filename=' + fileName);
            res.set('Content-Type', 'text/plain');
            readStream.pipe(res);
            //--------------------------------------

            }).catch( .....

What i want to do is when there is a POST, 1. grab the post information 2. do a res.render() 3. run a function with the post information as its parameters 4. do this code snippet that will allow the client to download stuff from the memory as a .txt file 5. do another res.render()

Everything works if we exclude the two res.render(). After i do one, i cannot set the headers. I get this error.

Error: Can't set headers after they are sent.

So i thought of a potential solution.

Is it possible that the app.post() will get the post data and do a res.render().

Then, return the post data, so another part of the code will handle calling the function with this data as parameter and then do the header manipulation thing, then finally do the last res.render().

Keep in mind this is the routes.js file.

回答1:

HTTP is a request/response protocol. A client makes a request and gets one and only one response back. So, you can never call res.render() twice on the same request.

Your problem is really defined by this desired sequence:

  1. Client sends request
  2. Server starts to process request
  3. Client shows progress
  4. Server finishes processing request
  5. Client shows final result

There are a number of ways to accomplish that:

Client uses Ajax instead of form post to send request

  1. Client submits form via Ajax instead of form post
  2. Client puts up progress on the page using DOM manipulation (changing of the current page contents, usually showing a visual overlay of some type)
  3. Server works on request, not returning anything yet
  4. Server finishes request and returns response to client with one res.render()
  5. Client either inserts the returned content into the current page or issues a window.location = xxxx to change the current page to show new URL containing new contents.

Form post response that uses webSocket/socket.io to get final results

  1. Client submits form
  2. Server returns immediately response page that shows progress/waiting UI and that page also connects a webSocket or socket.io connection to the server
  3. Server works on request
  4. Server accepts webSocket or socket.io connection
  5. Server finishes request and sends some type of result over webSocket/socket.io connection to the correct client
  6. Client receives response over webSocket/socket.io and either updates the contents of the current page or changes page to a new URL

All done via webSocket/socket.io

  1. Client loads original page
  2. Client establishes webSocket/socket.io connection to server
  3. Client sends form data to server over webSocket/socket.io connection
  4. Client puts up progress/waiting overlay
  5. Server starts processing request
  6. Server finishes processing request
  7. Server sends response from request back to client over webSocket/socket.io connection for that client.
  8. Client receives response over webSocket/socket.io connection and either updates the contents of the current page or changes page to a new URL