【发布时间】:2016-02-17 09:10:04
【问题描述】:
假设我有多个地方可以拨打response.send(someData)。现在我想创建一个全局拦截器,在其中捕获所有.send 方法并对someData 进行一些更改。 express.js有什么办法吗? (钩子、监听器、拦截器……)?
【问题讨论】:
标签: javascript node.js express
假设我有多个地方可以拨打response.send(someData)。现在我想创建一个全局拦截器,在其中捕获所有.send 方法并对someData 进行一些更改。 express.js有什么办法吗? (钩子、监听器、拦截器……)?
【问题讨论】:
标签: javascript node.js express
是的,这是可能的。有两种方法可以做到这一点,一种是使用提供拦截的库,并能够根据特定条件运行它: https://www.npmjs.com/package/express-interceptor
另一种选择是创建自己的中间件(用于 express),如下所示:
function modify(req, res, next){
res.body = "this is the modified/new response";
next();
}
express.use(modify);
【讨论】:
response 创建一个中间件,以便在statusCode 为200 时设置自定义标头,但如果我在中间件函数中运行console.log(res.statusCode),我总是会得到@987654327 @即使状态码是404401500。是否有另一种方法可以为响应获取正确的状态代码?
您可以定义如下中间件(取自 answer 并进行修改)
function modifyResponseBody(req, res, next) {
var oldSend = res.send;
res.send = function(data){
// arguments[0] (or `data`) contains the response body
arguments[0] = "modified : " + arguments[0];
oldSend.apply(res, arguments);
}
next();
}
app.use(modifyResponseBody);
【讨论】:
对于那些在谷歌上找到的人,根据最佳答案:
app.use((req, res, next) => {
let oldSend = res.send
res.send = function(data) {
console.log(data) // do something with the data
res.send = oldSend // set function back to avoid the 'double-send'
return res.send(data) // just call as normal with data
}
next()
})
【讨论】:
您可以简单地使用 NODEJS 和 Express 来完成,假设您正在调用 API 并希望在发送响应之前发送修改数据。
router.get('/id', (req,res) => {
... //your code here filling DATA
let testData = {
"C1": "Data1",
"C2": "Data2",
"yourdata": DATA
};
res.send(testData);
});
【讨论】:
只是想提供一个截取res.json的实际使用示例。
当我们写快递服务器时,我们可能会根据下面的情况在每个响应中发送status和message。
app.post('/test', (req, res) => {
res.json({status: 1, message: "some_error", otherData: "nothing"})
})
但是,如果我不想每次都写状态和消息怎么办?在使用res.json 时,我可以添加新函数来构建模板响应正文以发送数据。
const messageMap = {
0: "success",
1: "some_error"
}
app.use((req, res, next) => {
const originJson = res.json
res.json = (status, jsonData) => {
const fixedResponse = {
status,
message: messageMap[status]
}
originJson.call(res, {...jsonData, ...fixedResponse})
}
next()
})
那我只需要使用下面的函数。
app.get("/test", (req, res) => {
res.json(1, {otherData: 1})
})
您甚至可以使用构建器模式来执行此操作。
app.use((req, res) => {
res.buildFixedResponse = function (status) {
const fixedResponse = {
status,
message: messageMap[status]
}
res.json = function (jsonData) {
originJson.call(this, {...jsonData, ...fixedResponse})
}
return this
}
})
然后触发函数如下。
app.get("/test", (req, res) => {
res.buildFixedResponse(1).json({otherData: 1})
})
【讨论】:
就我而言,我必须使用带有 typicode/json-server 的中间件,并且能够获得一个不同的响应对象,而不仅仅是一个钝的 javascript 数组。
虽然typicode/json-server 的响应类似于:
[
{
...
}
]
应用中间件后:
module.exports = (req, res, next) => {
const oldSend = res.send;
res.send = (data) => {
const oldData = JSON.parse(data);
// we want to change the response only if a blunt array is sent
// also, we do this for the old sake of not sending json arrays
if(Object.prototype.toString.call(oldData) === '[object Array]') {
data = {
data: oldData
};
}
res.send = oldSend;
return res.send(data);
};
next();
}
响应如下:
{
data: [
{
...
}
]
}
【讨论】: