Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Express.js response status code with jsonp payload

I have a MEAN-stack backend where I'd like to respond with

return res.status(400).jsonp({
  message: 'Parsing failed.',
  code: '123'
});

When an angular app uses this JSONP endpoint and encounters this particular error, it receives a 400 but without its payload. When I change the status to 200/300 it comes through fine, with 400/500 it doesn't.

On other routes (POST) I can respond with a 4** status code and payload without any issues.

return res.status(400).send({
  message: 'Codes do not match.',
  code: '234'
});

Any Idea what I'm overlooking?

like image 958
Tom Avatar asked Jun 02 '16 12:06

Tom


People also ask

How do I send a status code in response Nodejs?

To send the status code to the client-side, you can method chain using the . send() method. The status code 404 tells the client side that the data requested is not found.

What is RES Statuscode?

res.status(code) Sets the HTTP status for the response. It is a chainable alias of Node's response.

What is Express JSON ()?

json() is a built-in middleware function in Express. This method is used to parse the incoming requests with JSON payloads and is based upon the bodyparser. This method returns the middleware that only parses JSON and only looks at the requests where the content-type header matches the type option.

Does Res send end the function?

send doesn't return the function, but does close the connection / end the request.


1 Answers

It looks like this is a browser-thing: when a remote script is requested (as is the case with JSONP requests), and the response returns a 400 (or higher) HTTP status, any code that may still get returned in the response body isn't evaluated (this actually makes perfect sense).

Angular will only know that the response has been sent, and that it had an error status, but since the callback wasn't called, there is no payload data to pass to your callback.

I tested a standalone HTML page:

<script>
function foo(data) { alert('foo') }
</script>
<script src="/endpoint?callback=foo"></script>

And the following Express handler:

app.get('/endpoint', (req, res) => {
  return res.status(400).jsonp({ hello : 'world' });
});

A 400 status doesn't trigger the alert, a 200 status does. It also doesn't work if the handler returns plain JS (acting like a simple .js file that gets loaded with a <script src=...>).

So for JSONP requests, you should stick to 200 responses and convey any errors in some other way (like setting an error property in the response object).

like image 116
robertklep Avatar answered Oct 21 '22 07:10

robertklep