Express.JS:如何按名称而不是数字设置响应状态?
Posted
技术标签:
【中文标题】Express.JS:如何按名称而不是数字设置响应状态?【英文标题】:Express.JS: how can I set response status by name rather than number? 【发布时间】:2013-08-21 03:20:20 【问题描述】:好的,大家都知道200是可以的,404是找不到的。但我对于诸如永久重定向与临时重定向、需要付款或其他更奇特的 HTTP 错误代码之类的事情,最好执行以下操作:
response.status('REQUEST_ENTITY_TOO_LARGE');
而不仅仅是使用通常被认为是不好的做法的幻数。当然,我可以在某个对象中有 413:'REQUEST_ENTITY_TOO_LARGE',但 Express 已经有状态代码 -> 名称映射的副本,我不想复制它。
如何在 Express JS 中按名称指定响应状态?
编辑:感谢@Akshat 指出 http.STATUS_CODES。详细说明他的答案,因为这些值本身是独一无二的,所以可以运行:
var statusCodeByName = ;
for ( var number in http.STATUS_CODES )
statusCodeByName[http.STATUS_CODES[number]] = number
这允许一个人:
> statusCodeByName['Request Entity Too Large']
'413'
【问题讨论】:
为什么用数字回答不好?这个数字很容易被浏览器理解,如果你试着不发送它,那么浏览器怎么能分辨出 404 和 500 之间的区别? @AlbertoZaccagni 显然我们需要通过网络发送一个号码,这是 RFC2616 所要求的。我之所以能够按名称指定状态(显然仍按数字发送)是为了便于阅读。 【参考方案1】:有一个专门用于此目的的 Node 模块:http-status-codes。
https://www.npmjs.org/package/http-status-codes
文档是这样说的:
安装
npm install http-status-codes
用法
var HttpStatus = require('http-status-codes');
response.send(HttpStatus.OK);
response.send(
HttpStatus.INTERNAL_SERVER_ERROR,
error: HttpStatus.getStatusText(HttpStatus.INTERNAL_SERVER_ERROR)
);
【讨论】:
【参考方案2】:HTTP 响应代码不是幻数;他们是规范。描述性文字只是一个有用的提醒,但协议本身依赖于那些状态码,核心的非常值得学习。两个想法。您当然可以在文件顶部创建一个常量并执行以下操作:
var REQUEST_ENTITY_TOO_LARGE = 413;
response.status(REQUEST_ENTITY_TOO_LARGE);
但是,大多数 REST API 只实现以下响应:
200 - OK
201 - Created # Response to successful POST or PUT
302 - Found # Temporary redirect such as to /login
303 - See Other # Redirect back to page after successful login
304 - Not Modified
400 - Bad Request
401 - Unauthorized # Not logged in
403 - Forbidden # Accessing another user's resource
404 - Not Found
500 - Internal Server Error
最后,如果有帮助,我将分享我们用于呈现自定义错误页面的代码:
module.exports = function(app)
app.use(function(req, res)
// curl https://localhost:4000/notfound -vk
// curl https://localhost:4000/notfound -vkH "Accept: application/json"
res.status(404);
if (req.accepts('html'))
res.render('error/404', title:'404: Page not found', error: '404: Page not found', url: req.url );
return;
if (req.accepts('json'))
res.send( title: '404: Page not found', error: '404: Page not found', url: req.url );
);
app.use( function(err, req, res, next)
// curl https://localhost:4000/error/403 -vk
// curl https://localhost:4000/error/403 -vkH "Accept: application/json"
var statusCode = err.status || 500;
var statusText = '';
var errorDetail = (process.env.NODE_ENV === 'production') ? 'Sorry about this error' : err.stack;
switch (statusCode)
case 400:
statusText = 'Bad Request';
break;
case 401:
statusText = 'Unauthorized';
break;
case 403:
statusText = 'Forbidden';
break;
case 500:
statusText = 'Internal Server Error';
break;
res.status(statusCode);
if (process.env.NODE_ENV !== 'production' && process.env.NODE_ENV !== 'test')
console.log(errorDetail);
if (req.accepts('html'))
res.render('error/500', title: statusCode + ': ' + statusText, error: errorDetail, url: req.url );
return;
if (req.accepts('json'))
res.send( title: statusCode + ': ' + statusText, error: errorDetail, url: req.url );
);
;
【讨论】:
幻数是出现在代码中没有名称的任何数字(通常不包括 0 和 1) - 请参阅 en.wikipedia.org/wiki/…。 “描述性文本”实际上是规范的一部分 - 请参阅w3.org/Protocols/rfc2616/rfc2616-sec10.html 的 RFC2616。此外,与其关注哪些状态代码受欢迎,不如关注哪些状态代码正确。【参考方案3】:除非您愿意自己更改源代码,否则这是不可能的。看看res.send
的implementation
如果您提供一个字符串作为参数,它只会将其解释为 html 并将响应发送为 200。
我认为 express 使用数字作为 HTTP 状态代码的原因是节点本身使用数字作为 http.STATUS_CODES 的对象键
【讨论】:
谢谢。 http.STATUS_CODES 是我一直在寻找的 - 由于值不重复,您可以想象创建一个带有反转键值的克隆并使用它。以上是关于Express.JS:如何按名称而不是数字设置响应状态?的主要内容,如果未能解决你的问题,请参考以下文章
如何让Spring的Data Rest Repository按名称而不是id来检索数据