处理node.js restify中的Accept标头

处理node.js restify中的Accept标头,node.js,http,restify,Node.js,Http,Restify,我试图通过使用ErrorAcceptError正确处理node.js/中RESTful API中的Accept头,如下所示 var restify=require('restify') ; server=restify.createServer() //将一些内容作为JSON与适当的HTTP头一起编写。 函数响应(状态、响应、内容类型、内容) {var json=json.stringify(内容) ;响应。写头(状态, {“内容类型”:内容类型 ,“内容编码”:“UTF-8” ,“内容长度”:

我试图通过使用
ErrorAcceptError
正确处理node.js/中RESTful API中的Accept头,如下所示

var restify=require('restify')
; server=restify.createServer()
//将一些内容作为JSON与适当的HTTP头一起编写。
函数响应(状态、响应、内容类型、内容)
{var json=json.stringify(内容)
;响应。写头(状态,
{“内容类型”:内容类型
,“内容编码”:“UTF-8”
,“内容长度”:Buffer.bytellength(json,'utf-8')
})
;response.write(json)
;response.end()
}
get('/api',函数(请求、响应、下一步)
{var contentType=“application/vnd.me.org.api+json”
;var properContentType=request.accepts(contentType)
;如果(PropertContentType!=contentType)
{返回下一步(new restify.ErrorAcceptError(“仅提供”+contentType))}
响应(200,响应,内容类型,
{“uri”:http://me.org/api"
,“用户”:“/用户”
,“团队”:“/团队”
})
;返回下一个()
});
listen(8080,function(){});
如果客户端提供了正确的
Accept
标题,或者没有标题(如图所示),则该选项可以正常工作:

$ curl -is http://localhost:8080/api
HTTP/1.1 200 OK
Content-Type: application/vnd.me.org.api+json
Content-Encoding: UTF-8
Content-Length: 61
Date: Tue, 02 Apr 2013 10:19:45 GMT
Connection: keep-alive

{"uri":"http://me.org/api","users":"/users","teams":"/teams"}
问题是,如果客户端确实提供了错误的
Accept
头,服务器将不会发送错误消息:

$ curl -is http://localhost:8080/api -H 'Accept: application/vnd.me.org.users+json'
HTTP/1.1 500 Internal Server Error
Date: Tue, 02 Apr 2013 10:27:23 GMT
Connection: keep-alive
Transfer-Encoding: chunked
因为假定客户机不理解错误消息(JSON格式),如下所示 由此可以看出:

$ curl -is http://localhost:8080/api -H 'Accept: application/json'
HTTP/1.1 406 Not Acceptable
Content-Type: application/json
Content-Length: 80
Date: Tue, 02 Apr 2013 10:30:28 GMT
Connection: keep-alive

{"code":"WrongAccept","message":"Only provides application/vnd.me.org.api+json"}

因此,我的问题是,我如何强制发回正确的错误状态代码和正文,或者我做错了什么?

问题实际上是,您返回的JSON对象的内容类型(
application/vnd.me.org.api+JSON
)是Restify不知道的(因此,创建了一个错误
找不到格式化程序

您需要告诉Restify如何格式化您的响应:

错误的
正文instanceof Error
也是必需的,因为它必须先转换为JSON,然后才能发送回客户端


*/*
构造创建了一个“一网打尽”的格式化程序,用于Restify无法自行处理的所有mime类型(该列表是
application/javascript
application/json
text/plain
application/octet-stream
)。我可以想象,在某些情况下,catch-all格式化程序可能会出现问题,但这取决于您的具体设置。

问题实际上是,您返回的JSON对象的内容类型(
application/vnd.me.org.api+JSON
)是Restify不知道的(因此,会创建一个错误
找不到格式化程序

您需要告诉Restify如何格式化您的响应:

错误的
正文instanceof Error
也是必需的,因为它必须先转换为JSON,然后才能发送回客户端


*/*
构造创建了一个“一网打尽”的格式化程序,用于Restify无法自行处理的所有mime类型(该列表是
application/javascript
application/json
text/plain
application/octet-stream
)。我可以想象,在某些情况下,catch-all格式化程序可能会出现问题,但这取决于您的具体设置。

我不使用格式化程序的原因是我有许多不同的MIME类型;通过使用上述单个
respond
函数,我不必列举所有这些函数。无论如何,我的问题确实是后者:我如何处理只接受未知MIME类型的客户端?我编辑了我的答案,似乎Restify确实有一个全面格式化程序的概念。我不使用格式化程序的原因是我有许多不同的MIME类型;通过使用上述单个
respond
函数,我不必列举所有这些函数。无论如何,我的问题确实是后者:如何处理只接受未知MIME类型的客户机?我编辑了我的答案,似乎Restify确实有一个全面格式化程序的概念。
server = restify.createServer({
  formatters : {
    '*/*' : function(req, res, body) { // 'catch-all' formatter
      if (body instanceof Error) { // see text
        body = JSON.stringify({
          code    : body.body.code,
          message : body.body.message
        });
      };
      return body;
    }
  }
});