NodeJS:validation请求types(检查JSON或HTML)

我想检查我的客户端请求的types是JSON还是HTML,因为我希望我的路线能同时满足人和机器的需求。

我已阅读Express 3文档:

http://expressjs.com/api.html

有两个方法req.accepts()req.is() ,像这样使用:

 req.accepts('json') 

要么

 req.accepts('html') 

由于这些工作不正常,我尝试使用:

 var requestType = req.get('content-type'); 

要么

 var requestType = req.get('Content-Type'); 

requestType始终undefined

使用这个线程的build议:

使用.is()检查请求types的Express.js不起作用

也不起作用。 我究竟做错了什么?


编辑1 :我已经检查了正确的客户端HTML协商。 这里是我的两个不同的请求标题(从debugging器检查器):

HTML: Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8

JSON: Accept: application/json, text/javascript, */*; q=0.01 Accept: application/json, text/javascript, */*; q=0.01


解决scheme (感谢Bret):

原来,我指定了Accept标头错误, */*是问题。 这是有用的代码!

 //server (now works) var acceptsHTML = req.accepts('html'); var acceptsJSON = req.accepts('json'); if(acceptsHTML) //will be null if the client does not accept html {} 

我正在使用JSTREE,一个使用jQuery Ajax调用的jQuery插件)。 传递给Ajax调用的参数在“ajax”字段中,并且我用一个完整的“headers”对象replace了“accepters”参数。 现在,它的工作,并应该解决这个问题,当你使用普通的jQuery,如果它应该发生。

 //client .jstree({ // List of active plugins "plugins" : [ "themes","json_data","ui","crrm","cookies","dnd","search","types","hotkeys","contextmenu" ], "json_data" : { "ajax" : { // the URL to fetch the data "url" : function(n) { var url = n.attr ? IDMapper.convertIdToPath(n.attr("id")) : "<%= locals.request.protocol + "://" + locals.request.get('host') + locals.request.url %>"; return url; }, headers : { Accept : "application/json; charset=utf-8", "Content-Type": "application/json; charset=utf-8" } } } }) 

var requestType = req.get('Content-Type'); 如果在请求中实际指定了内容types(我刚刚在一分钟之前重新validation了这个),它肯定会起作用。 如果没有定义内容types,它将是未定义的。 请记住,通常只有POST和PUT请求会指定一个内容types。 其他请求(如GET)通常会指定一个可接受types的列表,但这显然不是一回事。

编辑:

好吧,我现在明白你的问题了。 你正在谈论的是接受:标题,而不是内容types。

以下是发生了什么情况:请注意列出的接受types末尾的*/*;q=0.8 ? 这基本上说“我会接受任何东西”。 因此, req.accepts('json')总是返回"json"因为从技术上讲它是一个可接受的内容types。

我想你想要的是看是否application/json明确列出,如果是的话,在JSON响应,否则在HTML响应。 这可以通过几种方法来完成:

 // a normal loop could also be used in place of array.some() if(req.accepted.some(function(type) {return type.value === 'application/json';}){ //respond json } else { //respond in html } 

或者使用简单的正则expression式:

 if(/application\/json;/.test(req.get('accept'))) { //respond json } else { //respond in html } 

稍后,但我发现这对我来说是一个更好的解决scheme:

 req.accepts('html, json') === 'json' 

希望能帮助到你!

请定义“ 不应该工作 ”,因为他们为我做。

换一种说法:

 // server.js console.log('Accepts JSON?', req.accepts('json') !== undefined); // client sends 'Accept: application/json ...', result is: Accepts JSON? true // client sends 'Accept: something/else', result is: Accepts JSON? false 

由客户端发送的Content-Type头不用于内容协商,而是用于声明任何主体数据的内容types(如使用POST请求)。 这是为什么req.is()不是你的情况下调用的正确方法,因为它检查Content-Type