Serve either JSON or HTML based on what was requested? - json

I'm using nodejs and I want to make a unified handler to serve either JSON or HTML based on which one was requested from the client.
So far I though of simply passing a variable in the request body that I can check before serving
app.use(function(req, res) {
if (req.body.requested=='JSON')
res.json(...
else
res.render(...
But instead of passing the variable in request body, is there something in the headers or something intrinsically different between jQuery.getJSON() and jQuery.get() that I use to make the differentiation?

Yes, a better way is to simply check the Accept header of the request. For example, if the header says:
Accept: application/json
then it is appropriate to send JSON back. Or for example,
Accept: text/html
then you send back html.

Related

Node.js express res.json behavior

I have been working on one of my projects using node and ng4
when I came across using res.json to send an array back to Angular 4 front end, like res.json(arrayResult). Surprisingly, I cannot use JSON.parse(arrayResult) after Angular receives it because it throws an error saying unexpected end of input. I however can access all the data through result[i], just like any normal array.
I don't quite understand why res.json() does not send my array as a string to the front end. Is there any internal conversion involved? Why I could access the content through index without even parsing it or doing any conversion with it?
The server indeed send your json data as a string. Additionally to the string, the server passes Content-Type header to your client which tells your client what kind of data you received.
So if the Content-Type was text/html your client would think that he received an HTML file.
In your case, res.json using Content-Type: application/json which tells the client that the string that he got is actually a json object, so no need for you to use JSON.parse.
You can see the Content-Type under the response headers property.

PhpStorm/WebStorm REST client: easy way to send JSON?

In 2017 versions of PhpStorm / WebStorm there is a REST client we can use to send requests and analyze responses.
By default, when I send a POST and use the easy form in the UI to create request params, the parameters are formatted as x-www-form-urlencoded
instrument=JPY&id=6
I want to send data as JSON. So I thought if I add the content-type: application/json header, the IDE would format the request params accordingly, but it doesn't.
Currently the only way I see to send stuff in JSON format is to craft the JSON myself and put it in the Request Body as Text section of the IDE
Am I missing an easy way to send JSON?
You're not missing it, it's not there yet. Please vote: https://youtrack.jetbrains.com/issue/WEB-17342

How to build a form to POST this data example

I can send this successfully using the Postman Chrome extension with RAW data as below. How do I to build a HTML form, with fields to input message/badge/status and POST the data?
POST /rest/push/msg HTTP/1.1
Host: api.appery.io
X-Appery-Push-API-Key: myKey
Content-Type: application/json
Cache-Control: no-cache
{"payload":{"message":"Rockets important message","badge":"1"},"status":"sent"}
You can't.
There are a few ways that a form can encode data, but JSON is not currently one of them. There is a proposal to change that, but I'm not aware of any browser implementation in the wild.
Aside from that, a regular form submission doesn't support the addition of custom request headers (such as X-Appery-Push-API-Key).
If you want to make that request from a webpage, you'll have to construct it using JavaScript and send it with the XMLHttpRequest object (which would be subject to the Same Origin Policy).

How to emit JSON errors from JSON handlers without redefining `errorHandler` for the whole app?

I'm trying to build a site with a JSON-service inside it. So I want to have a different error handling for different handlers. For example, notFound must return HTML "Not found" in Handler Html and JSON value {"error": "not found"} in Handler Value. How can I achieve it?
Even when I'm using my own notFoundJson, Yesod's get404 doesn't and returns HTML even inside Handler Value.
Should I get return type of a handler inside errorHandler?
Should I make /api a subsite and override errorHandler for it?
Should I make another yesod, with its own specific errorHandler, and connect it to the main yesod as a subsite?
Simple solution: You haven't to do anything. It is a client's concern.
According to defaultErrorHandler implementation, the proper way to receive JSON error for client seems to be to provide HTTP header Accept: application/json or query parameter ?_accept=application/json in request.
defaultErrorHandler itself provides two representations: one for text/html client and one for application/json client. Default is the former.
More generic solution: Add a WAI middleware that appends HTTP header Accept: application/json or query parameter ?_accept=application/json for specific urls.

Do HTTP POST methods send data as a QueryString?

I'd like to know if the POST method on HTTP sends data as a QueryString, or if it use a special structure to pass the data to the server.
In fact, when I analyze the communication with POST method from client to server (with Fiddler for example), I don't see any QueryString, but a Form Body context with the name/value pairs.
The best way to visualize this is to use a packet analyzer like Wireshark and follow the TCP stream. HTTP simply uses TCP to send a stream of data starting with a few lines of HTTP headers. Often this data is easy to read because it consists of HTML, CSS, or XML, but it can be any type of data that gets transfered over the internet (Executables, Images, Video, etc).
For a GET request, your computer requests a specific URL and the web server usually responds with a 200 status code and the the content of the webpage is sent directly after the HTTP response headers. This content is the same content you would see if you viewed the source of the webpage in your browser. The query string you mentioned is just part of the URL and gets included in the HTTP GET request header that your computer sends to the web server. Below is an example of an HTTP GET request to http://accel91.citrix.com:8000/OA_HTML/OALogout.jsp?menu=Y, followed by a 302 redirect response from the server. Some of the HTTP Headers are wrapped due to the size of the viewing window (these really only take one line each), and the 302 redirect includes a simple HTML webpage with a link to the redirected webpage (Most browsers will automatically redirect any 302 response to the URL listed in the Location header instead of displaying the HTML response):
For a POST request, you may still have a query string, but this is uncommon and does not have anything to do with the data that you are POSTing. Instead, the data is included directly after the HTTP headers that your browser sends to the server, similar to the 200 response that the web server uses to respond to a GET request. In the case of POSTing a simple web form this data is encoded using the same URL encoding that a query string uses, but if you are using a SOAP web service it could also be encoded using a multi-part MIME format and XML data.
For example here is what an HTTP POST to an XML based SOAP web service located at http://192.168.24.23:8090/msh looks like in Wireshark Follow TCP Stream:
Post uses the message body to send the information back to the server, as opposed to Get, which uses the query string (everything after the question mark). It is possible to send both a Get query string and a Post message body in the same request, but that can get a bit confusing so is best avoided.
Generally, best practice dictates that you use Get when you want to retrieve data, and Post when you want to alter it. (These rules aren't set in stone, the specs don't forbid altering data with Get, but it's generally avoided on the grounds that you don't want people making changes just by clicking a link or typing a URL)
Conversely, you can use Post to retrieve data without changing it, but using Get means you can bookmark the page, or share the URL with other people, things you couldn't do if you'd used Post.
http://en.wikipedia.org/wiki/GET_%28HTTP%29
http://en.wikipedia.org/wiki/POST_%28HTTP%29
As for the actual format of the data sent in the message body, that's entirely up to the sender and is specified with the Content-Type header. If not specified, the default content-type for HTML forms is application/x-www-form-urlencoded, which means the server will expect the post body to be a string encoded in a similar manner to a GET query string. However this can't be depended on in all cases. RFC2616 says the following on the Content-Type header:
Any HTTP/1.1 message containing an entity-body SHOULD include a
Content-Type header field defining the media type of that body. If
and only if the media type is not given by a Content-Type field, the
recipient MAY attempt to guess the media type via inspection of its
content and/or the name extension(s) of the URI used to identify the
resource. If the media type remains unknown, the recipient SHOULD
treat it as type "application/octet-stream".
A POST request can include a query string, however normally it doesn't - a standard HTML form with a POST action will not normally include a query string for example.
GET will send the data as a querystring, but POST will not. Rather it will send it in the body of the request.
If your post try to reach the following URL
mypage.php?id=1
you will have the POST data but also GET data.