如何使用Express/Node.js访问Amazon SNS帖子正文
我正在这个框架之上的Node.js中重建一个PHP应用程序 应用程序的一部分是发布到的回调url SNS的帖子正文目前在PHP中以以下方式读取(有效): 在Express中,我尝试了以下方法:如何使用Express/Node.js访问Amazon SNS帖子正文,node.js,express,amazon-sns,Node.js,Express,Amazon Sns,我正在这个框架之上的Node.js中重建一个PHP应用程序 应用程序的一部分是发布到的回调url SNS的帖子正文目前在PHP中以以下方式读取(有效): 在Express中,我尝试了以下方法: app.post('/notification/url', function(req, res) { console.log(req.body); }); 但是,通过观察控制台,在发布post时,仅记录以下内容: {} 因此,要重复这个问题:如何使用Express/Node.js访问Amazo
app.post('/notification/url', function(req, res) {
console.log(req.body);
});
但是,通过观察控制台,在发布post时,仅记录以下内容:
{}
因此,要重复这个问题:如何使用Express/Node.js访问Amazon SNS帖子正文看看——它可以访问所有AWS服务端点
var sns = new AWS.SNS();
// subscribe
sns.subscribe({topic: "topic", Protocol: "https"}, function (err, data) {
if (err) {
console.log(err); // an error occurred
} else {
console.log(data); // successful response - the body should be in the data
}
});
// publish example
sns.publish({topic: "topic", message: "my message"}, function (err, data) {
if (err) {
console.log(err); // an error occurred
} else {
console.log(data); // successful response - the body should be in the data
}
});
EDIT:问题在于标准正文解析器不能处理纯文本,而纯文本正是SNS发送的内容类型。下面是提取原始主体的代码。将其放在身体分析器前面:
app.use(function(req, res, next) {
var d= '';
req.setEncoding('utf8');
req.on('d', function(chunk) {
d+= chunk;
});
req.on('end', function() {
req.rawBody = d;
next();
});
});
然后,您可以使用:
JSON.stringify(req.rawBody));
在您的路径中创建一个javascript对象,并对SNS post进行适当的操作
您还可以修改主体解析器来处理文本/纯文本,但修改中间件不是一个好主意。只需使用上面的代码。这是基于AlexGad的回答。尤其是以下评论: 标准express解析器将只处理application/json、application/x-www-form-encoded和multipart/form数据。我在上面添加了一些代码来放置在您的主体解析器之前
另一种方法是修复内容类型标题 以下是执行此操作的中间件代码:
exports.overrideContentType = function(){
return function(req, res, next) {
if (req.headers['x-amz-sns-message-type']) {
req.headers['content-type'] = 'application/json;charset=UTF-8';
}
next();
};
}
这假设根项目目录中有一个名为util.js的文件,其中包含:
util = require('./util');
在您的app.js中,并通过以下方式调用:
app.use(util.overrideContentType());
以前
app.use(express.bodyParser());
在app.js的文件中。这允许bodyParser()正确地分析主体
更少的干扰,然后您可以正常访问请求正文。假设您正在使用正文解析器,下面是如何做到这一点的 只需在app.js中添加以下行:
app.use(bodyParser.json());
app.use(bodyParser.text({ type: 'text/plain' }));
这些信息也可以在body parser官方文件中找到:我认为这可能是一个更早的阶段。我的申请已经订阅了。我可以在控制台上看到SNS的帖子,但我无法访问帖子的主体。啊,收到了,对不起。我现在明白你在做什么了。我相信SNS以文本/纯文本的形式发送内容,即使文本是JSON格式。你是如何设置你的身体分析器的?标准express解析器将只处理application/json、application/x-www-form-encoded和multipart/form数据。我在上面添加了一些代码来放置在您的主体解析器之前。它将根据您的请求为您提供一个原始体,您可以对其进行测试,以确保您从SNS获取数据。记录这个,然后你可能需要编写自己的身体分析器。我无法让它工作。不过,它确实为我指出了req.on和分块的正确方向,所以感谢您的输入。我把我的解决方案作为公认的答案。这是一个很好的答案,特别是如果你想使用同一个应用程序来处理来自SNS的通知和订阅确认。AWS使用
text/plain
作为内容类型有何原因?处理这件事真让人头疼。很高兴有一个解决方案,看看并得出自己的结论。注意日期。与其试图找到解决问题的替代方案,不如让AWS来解决它。作为上下文:这种(合理的、幼稚的)方法失败的原因是SNS HTTP设置。“Content-Type:text/plain;charset=UTF-8”请参见:(SNS并不是真正的grok JSON)技术上正确,投票率较高的帖子是命名问题的“更干净”解决方案。让经过良好测试的框架完成工作。。。
app.use(express.bodyParser());
app.use(bodyParser.json());
app.use(bodyParser.text({ type: 'text/plain' }));