1
votes

I want my node.js server to send different content based on request's content type, my server code is like this

    if(req.accepts('text/html')){
        console.log("accepts('text/html')");
        locals.page = 'posts';                  
        res.render('question.ejs', locals.questions);
    }
    else if(req.accepts('application/json')){   
        console.log("'application/json'");          
        res.json(200,locals.questions);
    }

There is a similar post but only for android client in node.js express, how to tell the HTTP request is application/json or html on the content negoition

This is my Jquery code

$.ajax({ type: "GET", url: "/course/abc/questions", contentType:"application/json; charset=utf-8", dataType:"json", success: function(data){ console.log(data.length,data); } });

For some reason, even I set the content type on appication/json, the node.js server side still accepts html rather than json.

A little strange

2

2 Answers

2
votes

The headers are different on the GET request (jquery) vs the response (express). On the request/browser/jquery/ajax side, when making a GET request, you set the Accept header, meaning "I would like to get back one of these formats". There is no Content-Type header because a GET request has no body, thus that header is not applicable.

On the server side, you set Content-Type, meaning "this response body is of the following format". The semantics of accept can be a list of alternative formats, whereas content-type is just a single value.

Here's a snippet copied from this answer

$.ajax({
    headers: { 
        Accept : "application/json; charset=utf-8"
    },
    success : function(response) {
        ...
    }
})
0
votes

Might be worth brushing up on your header field definitions...

I question whether you really should be returning content-type based on the Content-Type header.

TLDR;

  • Accept - used by the requestor to specify which media types are acceptable for the response
  • Content-Type - indicates the media type of body that the requestor is sending to the recipient

So my first recommendation - use the right tool for the job, send the Accept header in the request.

Now, you can make use of the req.accepts express function, which was built to do exactly what you want (i.e. ask the client what data format they prefer).

e.g.

const accept = req.accepts(['html', 'json'])
if (accept === 'html') {
    // res.send(...)
} else if (accept === 'json') {
    // res.json(...)
} else {
    // send 406 Not acceptable
}