Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Using Express.js and NodeJS, Can you send JSON via redirect in the response body

I am trying to send JSON via a 302 redirect. Is that possible in ExpressJS. The API states that a body can be added the res.json(). For example:

res.json(302, {'name': 'larry'}).

On the receiving end (where the redirect goes too) the body is empty. Here is some sample code:

Sending App

app.get('/hello', function(req,res){
  var data = {'name': 'larry'};
  res.set('location', 'http://www.example.com/sending');
  res.json(302, data);
});

Receiving App

app.get('/sending', function(req,res){
  console.log('Body: ' + req.body)
  res.send(req.body);
});

Note: the response headers for the 302 show a correct content-length of the data, but the receiving end shows an empty object.

like image 564
Dustin Davidson Avatar asked Jan 28 '14 23:01

Dustin Davidson


1 Answers

Your code doesn't make sense. In the first route, you tell Express to respond with a 302 redirect and send some data. It is sending your JSON to the client, something you can see in the fact that you're getting a correct Content-Length.

However, your second route can't work. Firstly, GET requests cannot have a body; req.body will always be empty.

Secondly, it looks like you're assuming a client receiving a redirect will resubmit the entity-body of the redirect response in its request to the target (example.com/sending in this case). This is incorrect.

  • A spec-compliant HTTP client will never send a server's response as the body of another request.
  • HTTP clients traditionally treat a 302 like a 303, meaning that the request to the target URL is always a GET request, even if the original request was a POST. Thus, it is impossible for the redirected request to contain any kind of body.

If you want to send some kind of data to another server, you have two options:

  • Send the data on the query string with a 303 redirect.

    // I'll use the built-in querystring module to convert an object into
    // a properly URL-encoded query string.
    res.redirect(303, '/url?' + querystring.stringify(data));
    
  • Respond 200 and use browser-side trickery to POST the data to the real destination.

    res.send('<form id="redir" method="post" action="/url">' +
             '<input type="hidden" name="foo" value="bar">' +
             // ...
             '</form>' +
             '<script>document.getElementById("redir").submit()</script>');
    

    Ugly, but works if this is intended for browsers. It won't work with requests made by servers or other non-browser tools. You might also want to include a "Continue" submit button for the luddites that insist on browsing with JS disabled.

    I would only use this method if the amount of data you have will make the query string exceed the amount of characters practically allowable in a URL (~2048) or if the data payload contains sensitive content, which should generally not be included in the query string.

like image 193
josh3736 Avatar answered Sep 25 '22 08:09

josh3736