NodeJS:验证请求类型(检查JSON或HTML)

Joã*_*lva 17 json node.js express

我想检查我的客户端请求的类型是JSON还是HTML,因为我希望我的路由满足人力和机器需求.

我在以下网址阅读了Express 3文档:

http://expressjs.com/api.html

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

req.accepts('json') 
Run Code Online (Sandbox Code Playgroud)

要么

req.accepts('html') 
Run Code Online (Sandbox Code Playgroud)

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

var requestType = req.get('content-type');
Run Code Online (Sandbox Code Playgroud)

要么

var requestType = req.get('Content-Type');
Run Code Online (Sandbox Code Playgroud)

requestType总是undefined......

使用此主题的建议:

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

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


编辑1:我检查了正确的客户端HTML协商.以下是我的两个不同的请求标头(取自调试器检查器):

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标头错误,这*/*就是问题所在.这是有效的代码!

//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
{}
Run Code Online (Sandbox Code Playgroud)

我正在使用JSTREE,一个在下面使用jQuery Ajax调用的jQuery插件.传递给Ajax调用的参数位于"ajax"字段中,我已将"accepted"参数替换为完整的"headers"对象.现在它可以工作,并且应该在使用普通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"
                    }
                }
            }
        })
Run Code Online (Sandbox Code Playgroud)

Bre*_*and 14

var requestType = req.get('Content-Type');如果在请求中实际指定了内容类型,我肯定会工作(我刚刚在一分钟前重新验证了这一点).如果未定义内容类型,则将不确定.请记住,通常只有POST和PUT请求才会指定内容类型.其他请求(如GET)通常会指定一个已接受类型的列表,但这显然不是一回事.

编辑:

好的,我现在更好地理解你的问题.你在谈论Accept:标题,而不是content-type.

这是发生了什么:注意*/*;q=0.8列出的接受类型的最后?这基本上说"我会接受任何东西." 因此,req.accepts('json')总是会返回,"json"因为从技术上讲,它是一种可接受的内容类型.

我想你想要的是看是否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
}
Run Code Online (Sandbox Code Playgroud)

或使用简单的正则表达式:

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

  • 您的正则表达式应该是“/application\/json/”,没有“;”。字符集并不总是在 application/json 内容类型之后发送(例如使用 POSTMAN)。如果不是,则没有“;” 在字符串“application/json”之后。 (3认同)

jos*_*eda 9

有点晚了,但我发现这对我来说是一个更好的解决方案:

req.accepts('html, json') === 'json'
Run Code Online (Sandbox Code Playgroud)

希望能帮助到你!

  • 我不得不通过`req.accepts(['html','json'])==='json'` (5认同)