我正在玩 Nodejs 并通过构建一个小的 rest API 来表达。我的问题是,设置代码状态以及响应数据的最佳做法/最佳方法是什么?
让我用一点代码来解释(我不会放启动服务器所需的节点和表达代码,只是关心的路由器方法):
router.get('/users/:id', function(req, res, next) {
var user = users.getUserById(req.params.id);
res.json(user);
});
exports.getUserById = function(id) {
for (var i = 0; i < users.length; i++) {
if (users[i].id == id) return users[i];
}
};
https://i.stack.imgur.com/0EMs8.png
可以看到,状态显示200,就OK了。但这是最好的方法吗?是否存在我必须自己设置状态以及返回的 JSON 的情况?还是总是由快递处理?
比如我刚刚做了个快速测试,稍微修改了上面的get方法:
router.get('/users/:id', function(req, res, next) {
var user = users.getUserById(req.params.id);
if (user == null || user == 'undefined') {
res.status(404);
}
res.json(user);
});
如您所见,如果在数组中找不到用户,我将设置状态为 404。
非常欢迎提供资源/建议来了解有关此主题的更多信息。
你可以这样做:
res.status(400).json(json_response);
这会将 HTTP 状态代码设置为 400,即使在 express 4 中也可以使用。
express deprecated res.json(status, obj): Use res.status(status).json(obj) instead
因此,res.status(400).json(json_response)
现在是准确的。
使用 res.send
、res.json
等时,默认状态为 200。
您可以设置像 res.status(500).json({ error: 'something is wrong' });
这样的状态
我经常会做类似的事情...
router.get('/something', function(req, res, next) {
// Some stuff here
if(err) {
res.status(500);
return next(err);
}
// More stuff here
});
然后让我的错误中间件发送响应,并在出现错误时执行我需要做的任何其他事情。
另外:从 4.9.0 版本开始添加 res.sendStatus(status)
http://expressjs.com/4x/api.html#res.sendStatus
关于状态响应的良好做法是,可以预见的是,根据错误发送正确的 HTTP 状态代码(客户端错误为 4xx,服务器错误为 5xx),关于实际的 JSON 响应,没有“圣经”,但一个好主意可能是在成功的响应中将状态和数据作为根对象的 2 个不同属性发送(再次)(这样您就可以让客户端有机会从 HTTP 标头和有效负载本身捕获状态)和第三个属性解释在发生错误的情况下以人类可以理解的方式出错。
Stripe's API 在现实世界中的行为类似。
IE
好的
200, {status: 200, data: [...]}
错误
400, {status: 400, data: null, message: "You must send foo and bar to baz..."}
我在我的 Express.js 应用程序中使用它:
app.get('/', function (req, res) {
res.status(200).json({
message: 'Welcome to the project-name api'
});
});
获取包含以下属性的完整 HttpResponse 的标准方法
body //包含你的数据头 ok status statusText type url
在后端,这样做
router.post('/signup', (req, res, next) => {
// res object have its own statusMessage property so utilize this
res.statusText = 'Your have signed-up succesfully'
return res.status(200).send('You are doing a great job')
})
在 Frontend 上,例如在 Angular
中,只需执行以下操作:
let url = `http://example.com/signup`
this.http.post(url, { profile: data }, {
observe: 'response' // remember to add this, you'll get pure HttpResponse
}).subscribe(response => {
console.log(response)
})
res.status(500).jsonp(dataRes);
try {
var data = {foo: "bar"};
res.json(JSON.stringify(data));
}
catch (e) {
res.status(500).json(JSON.stringify(e));
}
发送错误响应的最佳方式是 return res.status(400).send({ message: 'An error has occurred' })
。
然后,在您的前端,您可以使用以下方法捕获它:
url: your_url,
method: 'POST',
headers: headers,
data: JSON.stringify(body),
})
.then((res) => {
console.log('success', res);
})
.catch((err) => {
err.response && err.response.data && this.setState({ apiResponse: err.response.data })
})
仅记录 err
是行不通的,因为您发送的消息对象驻留在 err.response.data
中。
希望有帮助!
你可以这样做
return res.status(201).json({
statusCode: req.statusCode,
method: req.method,
message: 'Question has been added'
});
对于 IIS
如果您使用 iisnode 通过 IIS 运行 nodejs,请记住默认情况下 IIS 会替换您发送的任何错误消息。
这意味着如果您发送 res.status(401).json({message: "Incorrect authorization token"})
,您将返回 You do not have permission to view this directory or page
。
可以通过将以下代码添加到 <system.webServer>
(source) 下的 web.config 文件来关闭此行为:
<httpErrors existingResponse="PassThrough" />
自 4.9.0 版起已添加 res.sendStatus(status)
您可以使用其中一种res.sendStatus()
|| res.status()
个方法
以下是 res.sendStatus()
|| 之间的区别res.status()
res.sendStatus(200) // equivalent to res.status(200).send('OK')
res.sendStatus(403) // equivalent to res.status(403).send('Forbidden')
res.sendStatus(404) // equivalent to res.status(404).send('Not Found')
res.sendStatus(500) // equivalent to res.status(500).send('Internal Server Error')
我希望有人觉得这很有帮助谢谢
我没有看到有人提到 res
对象上的方法调用顺序很重要。我是 nodejs
的新手,起初并没有意识到 res.json() 不仅仅是设置响应的主体。它实际上也试图推断响应状态。所以,如果这样做:
res.json({"message": "Bad parameters"})
res.status(400)
第二行没有用,因为基于正确构建的 json express/nodejs
已经推断成功状态(200
)。
res.sendStatus(400);
也发送一个字符串数据,相当于res.status(400).send('Not Found')