【问题标题】:Handling Accept headers in node.js restify在 node.js 中处理 Accept 标头 restify
【发布时间】:2013-03-23 14:59:41
【问题描述】:

我正在尝试通过使用WrongAcceptError 在 node.js/restify 中正确处理 RESTful API 中的 Accept 标头,如下所示。

var restify = require('restify')
  ; server = restify.createServer()

// Write some content as JSON together with appropriate HTTP headers. 
function respond(status,response,contentType,content)
{ var json = JSON.stringify(content)
; response.writeHead(status,
  { 'Content-Type': contentType
  , 'Content-Encoding': 'UTF-8'
  , 'Content-Length': Buffer.byteLength(json,'utf-8')
  })
; response.write(json)
; response.end()
}

server.get('/api',function(request,response,next)
{ var contentType = "application/vnd.me.org.api+json"
; var properContentType = request.accepts(contentType)
; if (properContentType!=contentType)
  { return next(new restify.WrongAcceptError("Only provides "+contentType)) }
  respond(200,response,contentType,
  { "uri": "http://me.org/api"
  , "users": "/users"
  , "teams": "/teams"
  })
  ; return next()
});

server.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"}

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

【问题讨论】:

    标签: node.js http restify


    【解决方案1】:

    问题实际上是您返回的 JSON 对象具有 Restify 不知道的内容类型 (application/vnd.me.org.api+json)(因此会产生错误 no formatter found)。

    你需要告诉 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;
        }
      }
    });
    

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

    */* 构造创建了一个“包罗万象”的格式化程序,用于所有 Restify 无法自行处理的 mime 类型(该列表为 application/javascriptapplication/jsontext/plain 和 @987654329 @)。我可以想象在某些情况下,包罗万象的格式化程序可能会带来问题,但这取决于您的确切设置。

    【讨论】:

    • 我不使用格式化程序的原因是我有许多不同的 MIME 类型;通过使用如上所述的单个 respond 函数,我不必枚举所有这些函数。无论如何,我的问题确实是后者:如何处理只接受未知 MIME 类型的客户端?
    • 我编辑了我的答案,似乎 Restify 确实 有一个包罗万象的格式化程序的概念。
    猜你喜欢
    • 1970-01-01
    • 2012-08-15
    • 2013-07-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-01-30
    • 2019-02-10
    • 1970-01-01
    相关资源
    最近更新 更多